{"thread":{"id":"287","subject":"[RFC] updates for git-pull-script","startedAt":"2005-04-24T14:14:29Z","lastAt":"2005-04-24T19:55:32Z","messageCount":3,"participants":["James Bottomley","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"1523","messageId":"1114352069.4997.24.camel@mulgrave","threadId":"287","inReplyTo":null,"subject":"[RFC] updates for git-pull-script","fromName":"James Bottomley","fromEmail":"james.bottomley@steeleye.com","sentAt":"2005-04-24T14:14:29Z","receivedAt":"2005-04-24T14:14:29Z","isPatch":false,"sender":{"key":"james.bottomley@steeleye.com","avatar":null},"body":"The current git-pull-script has several behaviours that always trip me\nup\n\n1) when pulling from a local tree, you have to remember to append\nthe .git/ directory to the base\n2) It always tries to checkout the files ... this drives me nuts since I\ndon't have a lot of space on my laptop so I keep most trees empty.\n3) It doesn't attempt a more sophisticated merge.  The SCSI tree seems\nto be the one that always has added or removed files.  Since I think\ngit-merge-one-file-script is reasonably trustworthy, I made automatic\nmerges using it one of the pull features.\n4) It doesn't remember the old head.  This is useful for unpulling\n(pruning back to if the merge misfires) or simply seeing the changes\nbetween the old and new heads.\n\nThe attached addresses all these points.  It's what I use, but since\nothers may prefer the original behaviour, I'm sending it as a straw\nhorse.\n\nJames\n\n--- a/git-pull-script\n+++ b/git-pull-script\n@@ -3,9 +3,17 @@\n # use \"$1\" or something in a real script, this \n # just hard-codes it.\n #\n-merge_repo=$1\n+merge_repo=\"$1\"\n+\n+[  -d .git ] || die\n+\n+if [ -d \"$merge_repo\" -a -d \"$merge_repo/.git\" ]; then\n+\tmerge_repo=\"$merge_repo/.git\"\n+fi\n \n rm -f .git/MERGE_HEAD\n+rm -f .git/OLD_HEAD\n+cp .git/HEAD .git/OLD_HEAD\n \n echo \"Getting object database\"\n rsync -avz --ignore-existing $merge_repo/objects/. .git/objects/.\n@@ -32,17 +40,22 @@ if [ \"$common\" == \"$merge_head\" ]; then\n fi\n if [ \"$common\" == \"$head\" ]; then\n \techo \"Updating from $head to $merge_head.\"\n-\techo \"Destroying all noncommitted data!\"\n-\techo \"Kill me within 3 seconds..\"\n-\tsleep 3\n-\tread-tree -m $merge_tree && checkout-cache -f -a && update-cache --refresh\n+\techo \"Reading the current tree\"\n+\tread-tree -m $merge_tree || exit 1\n \techo $merge_head > .git/HEAD\n \texit 0\n fi\n echo \"Trying to merge $merge_head into $head\"\n read-tree -m $common_tree $head_tree $merge_tree\n-result_tree=$(write-tree) || exit 1\n-result_commit=$(echo \"Merge $merge_repo\" | commit-tree $result_tree -p $head -p $merge_head)\n+merge_msg=\"Merge $merge_repo\"\n+result_tree=$(write-tree 2>/dev/null)\n+if [ $? -ne 0 ]; then\n+\techo \"Simple merge failed, trying Automatic merge\"\n+\tmerge-cache git-merge-one-file-script -a\n+\tmerge_msg=\"Automatic merge of $merge_repo\"\n+\tresult_tree=$(write-tree) || exit 1\n+fi\n+result_commit=$(echo $merge_msg | commit-tree $result_tree -p $head -p $merge_head)\n echo \"Committed merge $result_commit\"\n echo $result_commit > .git/HEAD\n-checkout-cache -f -a && update-cache --refresh\n+#checkout-cache -f -a && update-cache --refresh\n\n\n"},{"id":"1534","messageId":"Pine.LNX.4.58.0504241045260.15879@ppc970.osdl.org","threadId":"287","inReplyTo":"1114352069.4997.24.camel@mulgrave","subject":"Re: [RFC] updates for git-pull-script","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-04-24T17:49:15Z","receivedAt":"2005-04-24T17:49:15Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 24 Apr 2005, James Bottomley wrote:\n> \n> The attached addresses all these points.  It's what I use, but since\n> others may prefer the original behaviour, I'm sending it as a straw\n> horse.\n\nI don't think anybody preferes the original behaviour - the reason \ngit-pull-script punted with any non-trivial merge was that when I wrote \nthe damn thing, I was still just testing out the merges, and I definitely \ndidn't trust the automated script.\n\nHowever, when you remove the \"checkout-cache -f -a\" thing, it means that \nyou are leaving all teh checked-out files in a state where it's _very_ \neasy to mess up later, and doign so silently really is very bad.\n\nSo at the _very_ least you should do an \"update-cache --refresh\", and \n_tell_ the user about the files that are checked-out but not up-to-date.\n\nAnd it really sounds like the whole and only reason you don't like \ncheckout-cache is that you normally work with an empty tree, so I actually \nthink that the _right_ answer for you is to add a new flag to \n\"checkout-cache\" that only updates files that already exist. Something \nlike \"-n\" for \"don't create new files\". \n\n\t\tLinus\n"},{"id":"1541","messageId":"1114372532.5188.4.camel@mulgrave","threadId":"287","inReplyTo":"Pine.LNX.4.58.0504241045260.15879@ppc970.osdl.org","subject":"Re: [RFC] updates for git-pull-script","fromName":"James Bottomley","fromEmail":"james.bottomley@steeleye.com","sentAt":"2005-04-24T19:55:32Z","receivedAt":"2005-04-24T19:55:32Z","isPatch":false,"sender":{"key":"james.bottomley@steeleye.com","avatar":null},"body":"On Sun, 2005-04-24 at 10:49 -0700, Linus Torvalds wrote:\n> I don't think anybody preferes the original behaviour - the reason \n> git-pull-script punted with any non-trivial merge was that when I wrote \n> the damn thing, I was still just testing out the merges, and I definitely \n> didn't trust the automated script.\n\nWell ... I kept checking it against BK for a while ... however it seems\nto do the right thing, so I've been happy ...\n\n> However, when you remove the \"checkout-cache -f -a\" thing, it means that \n> you are leaving all teh checked-out files in a state where it's _very_ \n> easy to mess up later, and doign so silently really is very bad.\n\nYes ... I really want the BK behaviour back where it would abort the\nupdate if a change has to be made to a file that I've already touched.\nI'm still thinking about how best to do this\n\n> So at the _very_ least you should do an \"update-cache --refresh\", and \n> _tell_ the user about the files that are checked-out but not up-to-date.\n> \n> And it really sounds like the whole and only reason you don't like \n> checkout-cache is that you normally work with an empty tree, so I actually \n> think that the _right_ answer for you is to add a new flag to \n> \"checkout-cache\" that only updates files that already exist. Something \n> like \"-n\" for \"don't create new files\". \n\nOK, look over the attached.  I added the -n option to checkout-cache and\nan --ignore-missing to update-cache.  Now if I add\n\ncheckout-cache -n -f -a && update-cache --ignore-missing --refresh\n\nit should do the right thing.\n\nJames\n\ncheckout-cache.c: f65be62b4abad184bd755884fb72681fc28c8b3b\n--- a/checkout-cache.c\n+++ b/checkout-cache.c\n@@ -34,7 +34,7 @@\n  */\n #include \"cache.h\"\n \n-static int force = 0, quiet = 0;\n+static int force = 0, quiet = 0, not_new = 0;\n \n static void create_directories(const char *path)\n {\n@@ -118,7 +118,8 @@ static int checkout_entry(struct cache_e\n \t\t * just do the right thing)\n \t\t */\n \t\tunlink(path);\n-\t}\n+\t} else if (not_new) \n+\t\treturn 0;\n \treturn write_entry(ce, path);\n }\n \n@@ -182,6 +183,10 @@ int main(int argc, char **argv)\n \t\t\t\tquiet = 1;\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(arg, \"-n\")) {\n+\t\t\t\tnot_new = 1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!memcmp(arg, \"--prefix=\", 9)) {\n \t\t\t\tbase_dir = arg+9;\n \t\t\t\tcontinue;\nupdate-cache.c: 4353b80890ba2afbe22248a4dc25060aa4a429b2\n--- a/update-cache.c\n+++ b/update-cache.c\n@@ -12,7 +12,23 @@\n  * like \"update-cache *\" and suddenly having all the object\n  * files be revision controlled.\n  */\n-static int allow_add = 0, allow_remove = 0;\n+static int allow_add = 0, allow_remove = 0, not_new = 0;\n+\n+/* Three functions to allow overloaded pointer return; see linux/err.h */\n+static inline void *ERR_PTR(long error)\n+{\n+\treturn (void *) error;\n+}\n+\n+static inline long PTR_ERR(const void *ptr)\n+{\n+\treturn (long) ptr;\n+}\n+\n+static inline long IS_ERR(const void *ptr)\n+{\n+\treturn (unsigned long)ptr > (unsigned long)-1000L;\n+}\n \n static int index_fd(unsigned char *sha1, int fd, struct stat *st)\n {\n@@ -172,7 +188,7 @@ static struct cache_entry *refresh_entry\n \tint changed, size;\n \n \tif (stat(ce->name, &st) < 0)\n-\t\treturn NULL;\n+\t\treturn ERR_PTR(-errno);\n \n \tchanged = cache_match_stat(ce, &st);\n \tif (!changed)\n@@ -183,10 +199,10 @@ static struct cache_entry *refresh_entry\n \t * to refresh the entry - it's not going to match\n \t */\n \tif (changed & MODE_CHANGED)\n-\t\treturn NULL;\n+\t\treturn ERR_PTR(-EINVAL);\n \n \tif (compare_data(ce, st.st_size))\n-\t\treturn NULL;\n+\t\treturn ERR_PTR(-EINVAL);\n \n \tsize = ce_size(ce);\n \tupdated = malloc(size);\n@@ -212,8 +228,9 @@ static void refresh_cache(void)\n \t\t}\n \n \t\tnew = refresh_entry(ce);\n-\t\tif (!new) {\n-\t\t\tprintf(\"%s: needs update\\n\", ce->name);\n+\t\tif (IS_ERR(new)) {\n+\t\t\tif (!(not_new && PTR_ERR(new) == -ENOENT))\n+\t\t\t\tprintf(\"%s: needs update\\n\", ce->name);\n \t\t\tcontinue;\n \t\t}\n \t\tactive_cache[i] = new;\n@@ -328,6 +345,10 @@ int main(int argc, char **argv)\n \t\t\t\ti += 3;\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(path, \"--ignore-missing\")) {\n+\t\t\t\tnot_new = 1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tdie(\"unknown option %s\", path);\n \t\t}\n \t\tif (!verify_path(path)) {\n\n\n"}]}