bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GNU-style ChangeLog merge driver for Git


From: Eric Blake
Subject: Re: GNU-style ChangeLog merge driver for Git
Date: Thu, 14 Feb 2008 16:48:28 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Bruno Haible <bruno <at> clisp.org> writes:

> Benoit Sigoure explained that what we need to solve this problem is a
> git "merge driver". Here is such a merge driver. It should solve the
> problem.
> 
> 
>     /* Heuristic to determine whether it's a pull in downstream direction
>        (e.g. pull from a centralized server) or a pull in upstream direction
>        (e.g. "git stash apply").
> 
>        For ChangeLog this distinction is important. The difference between
>        an "upstream" and a "downstream" repository is that more people are
>        looking at the "upstream" repository.  They want to be informed about
>        changes and expect them to be shown at the top of the ChangeLog.
>        When a user pulls downstream, on the other hand, he has two options:
>        a) He gets the change entries from the central repository also at the
>           top of his ChangeLog, and his own changes come after them.
>        b) He gets the change entries from the central repository after those
>           he has collected for his branch.  His own change entries stay at
>           the top of the ChangeLog file.
>        In the case a) he has to reorder the ChangeLog before he can commit.
>        No one does that.  So most people want b).
>        In other words, the order of entries in a ChangeLog should represent
>        the order in which they have flown (or will flow) into the *central*
>        repository.
> 
>        But in git this is fundamentally indistinguishable, because when Linus
>        pulls patches from akpm and akpm pulls patches from Linus, it's not
>        clear which of the two is more "upstream".  Also, when you have many
>        branches in a repository and pull from one to another, "git" has no way
>        to know which branch is more "upstream" than the other.  The git-tag(1)
>        manual page also says:
>        "One important aspect of git is it is distributed, and being
>         distributed largely means there is no inherent "upstream" or
>         "downstream" in the system."
>        Therefore anyone who attempts to produce a ChangeLog from the merge
>        history will fail.
> 
>        Here we allow the user to specify the pull direction through an
>        environment variable (GIT_UPSTREAM or GIT_DOWNSTREAM).  If these two
>        environment variables are not set, we assume a "simple single user"
>        usage pattern: He manages local changes through stashes and uses
>        "git pull" only to pull downstream.
> 
>        How to distinguish these situation? There are several hints:
>        - During a "git stash apply", GIT_REFLOG_ACTION is not set. During
>          a "git pull", it is set to 'pull'.
>        - During a "git stash apply", there is an environment variable of
>          the form GITHEAD_<40_hex_digits>='Stashed changes'.  */

Your heuristics guess wrong in at least one useful scenario.  As of git 1.5.4, 
you can do 'git pull --rebase', to rebase all your local changes on the current 
branch on top of whatever upstream changes were made in the meantime.  So I'm 
starting to use this new workflow for simple changes (note that I don't need to 
use the poor UI of 'git stash' with this workflow):

$ git branch # I'm working directly on master, with no topic branches
* master
$ # do some edits, including changelog
$ git commit -a -m 'Patch for ...'
...
$ git pull --rebase # check for any upstream changes in the meantime
First, rewinding head to replay your work on top of it...
HEAD is now at e3dce8b... Fix texinfo grammar.
Applying Patch for ...
error: patch failed: ChangeLog:1
error: ChangeLog: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merged ChangeLog
merging ChangeLog using GNU-style ChangeLog merge driver
$ # inspect ChangeLog

Oops - this put the upstream ChangeLog entries at the top of the file, in front 
of my entries which I am about to push upstream.  While I could 
do 'GIT_DOWNSTREAM= git pull --rebase', it would be nicer if you could make 
your heuristics recognize this mode of operation.

One other thing I've noticed.  The clcommit script (originally from the cvs-
utils project, which is now mostly defunct; but which is still actively 
distribtuted as part of the libtool project under the name commit) enforces the 
following abbreviated ChangeLog style when a single author makes two commits in 
one day:

2008-02-12  Eric Blake  <address@hidden>

        Silence warning in last patch.
        * lib/quotearg.c (quotearg_buffer_restyled): Add missing const.

        Quotearg part 4: add tests, fix c-maybe colon quoting.
        * lib/quotearg.h: Improve documentation.

rather than a full-blown:

2008-02-12  Eric Blake  <address@hidden>

        Silence warning in last patch.
        * lib/quotearg.c (quotearg_buffer_restyled): Add missing const.

2008-02-12  Eric Blake  <address@hidden>

        Quotearg part 4: add tests, fix c-maybe colon quoting.
        * lib/quotearg.h: Improve documentation.

The reason for this policy is that with the latter format, most diff engines 
show the difference as:

 2008-02-12  Eric Blake  <address@hidden>
 
+       Silence warning in last patch.
+       * lib/quotearg.c (quotearg_buffer_restyled): Add missing const.
+
+2008-02-12  Eric Blake  <address@hidden>
+
        Quotearg part 4: add tests, fix c-maybe colon quoting.
        * lib/quotearg.h: Improve documentation.

which mismatches the date line to the diff content (git's default diff engine 
included).  However, the abbreviated style does not currently work with your 
merge driver, since it treats the entire date-delimited chunk, containing two 
commits' entries, as a single commit description; and since it does not match 
any other entry, the merged result then ends up with two copies of the earlier 
entry:

2008-02-12  Eric Blake  <address@hidden>

        Silence warning in last patch.
        * lib/quotearg.c (quotearg_buffer_restyled): Add missing const.

        Quotearg part 4: add tests, fix c-maybe colon quoting.
        * lib/quotearg.h: Improve documentation.

2008-02-12  Eric Blake  <address@hidden>

        Quotearg part 4: add tests, fix c-maybe colon quoting.
        * lib/quotearg.h: Improve documentation.

I guess I can swap my mindset away from the abbreviated style, and thus avoid 
confusing the merge driver.  But it would be nice if your merge driver could 
recognize that usage.

It would also be nice if there were a custom diff driver to go alongside the 
custom merge driver, which would make the diff output correctly show the change 
markers on the full style using the date header alongside the rest of the 
current entry, rather than with the current mismatch between one entry's 
contents and the next entries date header.

P.S. Thanks again for writing this - the merge driver is already saving me some 
time!

-- 
Eric Blake






reply via email to

[Prev in Thread] Current Thread [Next in Thread]