* [PATCH] Preserve ORIG_HEAD if already up-to-date with remote. @ 2011-06-13 7:35 Kunal Gangakhedkar 2011-06-13 7:35 ` [PATCH] merge: " Kunal Gangakhedkar 0 siblings, 1 reply; 4+ messages in thread From: Kunal Gangakhedkar @ 2011-06-13 7:35 UTC (permalink / raw) To: gitster; +Cc: git, Kunal Gangakhedkar By default, the ORIG_HEAD ref is moved to point to HEAD during a merge. If there are no changes (i.e. if the local is in sync with remote), it becomes difficult to see the last set of changes as the range of commits is lost. This is especially true when the pull is performed via a cronjob or a script. Following this mail is a patch that tries to address the problem by not updating the ORIG_HEAD ref when it detects an empty merge (i.e. local is in sync with the remote). That way, one can still do diffstat/log between ORIG_HEAD..HEAD. It's still possible to revert to old behavior with: o. --force-update-orig-head cmd line option o. merge.forceupdateorighead config option Please review the patch and let me know if: a) it makes sense to have this functionality b) if the patch looks OK Please let me know if there are any changes required. I'll write the test cases and send them in another mail later. Thanks, Kunal Kunal Gangakhedkar (1): merge: Preserve ORIG_HEAD if already up-to-date with remote. builtin/merge.c | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) -- 1.7.6.rc1.2.g20c4a.dirty ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] merge: Preserve ORIG_HEAD if already up-to-date with remote. 2011-06-13 7:35 [PATCH] Preserve ORIG_HEAD if already up-to-date with remote Kunal Gangakhedkar @ 2011-06-13 7:35 ` Kunal Gangakhedkar 2011-06-14 23:14 ` Junio C Hamano 0 siblings, 1 reply; 4+ messages in thread From: Kunal Gangakhedkar @ 2011-06-13 7:35 UTC (permalink / raw) To: gitster; +Cc: git, Kunal Gangakhedkar Do not update ORIG_HEAD ref to current HEAD if the repo is already in-sync with the remote. Otherwise, it becomes difficult to keep track of last set of changes. With this patch, it's possible to do a diffstat/log for last set of changes even after a pull/merge that returns 'Already up-to-date'. This is especially useful when the pull is performed via a cronjob/script. The old behaviour can still be forced via: o. --force-update-orig-head cmd line option o. merge.forceupdateorighead config option Signed-off-by: Kunal Gangakhedkar <kunal.gangakhedkar@gmail.com> --- builtin/merge.c | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) diff --git a/builtin/merge.c b/builtin/merge.c index 325891e..6ac26f0 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -63,6 +63,7 @@ static int allow_rerere_auto; static int abort_current_merge; static int show_progress = -1; static int default_to_upstream; +static int force_update_orig_head = 0; static struct strategy all_strategy[] = { { "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL }, @@ -206,6 +207,8 @@ static struct option builtin_merge_options[] = { OPT_BOOLEAN(0, "abort", &abort_current_merge, "abort the current in-progress merge"), OPT_SET_INT(0, "progress", &show_progress, "force progress reporting", 1), + OPT_BOOLEAN(0, "force-update-orig-head", &force_update_orig_head, + "force-update ORIG_HEAD even if in sync with remote"), OPT_END() }; @@ -563,7 +566,11 @@ static int git_merge_config(const char *k, const char *v, void *cb) } else if (!strcmp(k, "merge.defaulttoupstream")) { default_to_upstream = git_config_bool(k, v); return 0; + } else if (!strcmp(k, "merge.forceupdateorighead")) { + force_update_orig_head = git_config_bool(k, v); + return 0; } + return git_diff_ui_config(k, v, cb); } @@ -1017,6 +1024,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) struct commit_list *common = NULL; const char *best_strategy = NULL, *wt_strategy = NULL; struct commit_list **remotes = &remoteheads; + int orig_head_updated = 0; if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_merge_usage, builtin_merge_options); @@ -1212,8 +1220,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix) free(list); } - update_ref("updating ORIG_HEAD", "ORIG_HEAD", head, NULL, 0, - DIE_ON_ERR); + if (force_update_orig_head) { + update_ref("updating ORIG_HEAD", "ORIG_HEAD", head, NULL, 0, + DIE_ON_ERR); + orig_head_updated = 1; + } if (!common) ; /* No common ancestors found. We need a real merge. */ @@ -1254,6 +1265,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix) finish(o->sha1, msg.buf); drop_save(); + if (!orig_head_updated) { + update_ref("updating ORIG_HEAD", "ORIG_HEAD", head, NULL, 0, + DIE_ON_ERR); + orig_head_updated = 1; + } return 0; } else if (!remoteheads->next && common->next) ; @@ -1306,6 +1322,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } } + if (!orig_head_updated) { + update_ref("updating ORIG_HEAD", "ORIG_HEAD", head, NULL, 0, + DIE_ON_ERR); + orig_head_updated = 1; + } + if (fast_forward_only) die(_("Not possible to fast-forward, aborting.")); -- 1.7.6.rc1.2.g20c4a.dirty ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] merge: Preserve ORIG_HEAD if already up-to-date with remote. 2011-06-13 7:35 ` [PATCH] merge: " Kunal Gangakhedkar @ 2011-06-14 23:14 ` Junio C Hamano 2011-07-17 16:31 ` Kunal Gangakhedkar 0 siblings, 1 reply; 4+ messages in thread From: Junio C Hamano @ 2011-06-14 23:14 UTC (permalink / raw) To: Kunal Gangakhedkar; +Cc: git Kunal Gangakhedkar <kunal.gangakhedkar@gmail.com> writes: > Do not update ORIG_HEAD ref to current HEAD if the repo is already > in-sync with the remote. > > Otherwise, it becomes difficult to keep track of last set of changes. > > With this patch, it's possible to do a diffstat/log for last set of > changes even after a pull/merge that returns 'Already up-to-date'. I am not sure what you mean. If you are behind remote A and remote B is behind remote A, i.e. You -- (fast forwards) --> B -- (fast forwards) --> A then you should be able to expect these: : point zero $ git pull A $ git diff/log ORIG_HEAD.. ;# shows how your tree and history # are updated wrt point zero above : point one $ git pull B $ git diff/log ORIG_HEAD.. ;# shows how your tree and history # are updated wrt point one above If your patch is to stop recording ORIG_HEAD for the second "git pull" above, I fail to see how that could be a good change. If you want to drive "pull" from a script (e.g. cron) and want to have precise control of what happens depending on how HEAD is updated, your script has enough freedom and flexibility to do so before running "pull", I think. E.g. . $(git --exec-path)/git-sh-setup CURRENT=$(git rev-parse HEAD^0) || die "Eh? No Head?" git pull || die "pull fails" UPDATED=$(git rev-parse HEAD^0) if test "$CURRENT" = "$UPDATED" then exit 0; # nothing happened fi git shortlog --no-merges $CURRENT..$UPDATED git diff --stat --summary $CURRENT..$UPDATED ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] merge: Preserve ORIG_HEAD if already up-to-date with remote. 2011-06-14 23:14 ` Junio C Hamano @ 2011-07-17 16:31 ` Kunal Gangakhedkar 0 siblings, 0 replies; 4+ messages in thread From: Kunal Gangakhedkar @ 2011-07-17 16:31 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Wednesday 15 Jun 2011 4:44:28 am Junio C Hamano wrote: > Kunal Gangakhedkar <kunal.gangakhedkar@gmail.com> writes: > > Do not update ORIG_HEAD ref to current HEAD if the repo is already > > in-sync with the remote. > > > > Otherwise, it becomes difficult to keep track of last set of changes. > > > > With this patch, it's possible to do a diffstat/log for last set of > > changes even after a pull/merge that returns 'Already up-to-date'. > > I am not sure what you mean. If you are behind remote A and remote B is > behind remote A, i.e. > > You -- (fast forwards) --> B -- (fast forwards) --> A > > then you should be able to expect these: > : point zero > > $ git pull A > $ git diff/log ORIG_HEAD.. ;# shows how your tree and history > # are updated wrt point zero above > > : point one > > $ git pull B > $ git diff/log ORIG_HEAD.. ;# shows how your tree and history > # are updated wrt point one above > > If your patch is to stop recording ORIG_HEAD for the second "git pull" > above, I fail to see how that could be a good change. > > If you want to drive "pull" from a script (e.g. cron) and want to have > precise control of what happens depending on how HEAD is updated, your > script has enough freedom and flexibility to do so before running "pull", > I think. E.g. > > . $(git --exec-path)/git-sh-setup > > CURRENT=$(git rev-parse HEAD^0) || die "Eh? No Head?" > git pull || die "pull fails" > UPDATED=$(git rev-parse HEAD^0) > if test "$CURRENT" = "$UPDATED" > then > exit 0; # nothing happened > fi > git shortlog --no-merges $CURRENT..$UPDATED > git diff --stat --summary $CURRENT..$UPDATED Sorry, got caught up in butt-load of work.. Well, that's not what I meant. The default diffstat at the end of merge/ff/pull already gives the required info. The problem comes when the remote _does not_ have updates since last pull. With a 'git pull' next time around (i.e. with no updates in the remote), ORIG_HEAD is moved to the current HEAD and the range of commits in the last changeset are lost. That is, I can no longer figure out the contents of the last changeset. To give an example, let's track the following sequence: $ git clone git://url/of/super-awesome/project.git (0) .... hack hack hack in remote .... .... remote is fast-forwarded ... $ git pull (1) ... you got the changes .... .... hack hack hack in remote .... .... remote is fast-forwarded ... $ git pull (2) ... you got the changes .... ... now, everybody is on vacation, so, no updates in remote ... $ git pull (3) ... you get 'Already up-to-date.' message ... ... everybody is still on vacation, so, no updates in remote ... $ git pull (4) ... you get 'Already up-to-date.' message ... In the current situation, at the end of (3) above, ORIG_HEAD is moved to the then HEAD. So, after (3), if I try to do git diff/log ORIG_HEAD.. I'd get an empty changeset - i.e. I've lost the *last updated* changeset information. What my patch does is keep ORIG_HEAD at its current state in (3) - so that changeset info is still available after (3) until there is an update in tracked branch of remote. At which point, ORIG_HEAD will be forwarded again to the then HEAD and HEAD will point to the newly merged HEAD to reflect the changes from remote. This way, the *latest* changeset is always available for inspection whether there's been an update in remote or not. I can safely do git diff/log ORIG_HEAD.. after (4) as well and I'd still get the required information. I've included config/cmdline options in the patch to force-update ORIG_HEAD so that current behavior is retained. Please let me know if it makes sense. I've written a simple test script for the functionality, but I'm not sure how to name it. Currently, in my working copy, it's called t5555-merge-preserve-orig-head.sh If that's fine, I'll send it in another patch for review. Otherwise, please suggest a good name for it. Thanks, Kunal ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-07-17 16:31 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-06-13 7:35 [PATCH] Preserve ORIG_HEAD if already up-to-date with remote Kunal Gangakhedkar 2011-06-13 7:35 ` [PATCH] merge: " Kunal Gangakhedkar 2011-06-14 23:14 ` Junio C Hamano 2011-07-17 16:31 ` Kunal Gangakhedkar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).