Wireshark-dev: Re: [Wireshark-dev] Quick start instructions for Gerrit
From: Evan Huus <eapache@xxxxxxxxx>
Date: Fri, 31 Jan 2014 22:33:30 -0500
On Fri, Jan 31, 2014 at 7:10 PM, Evan Huus <eapache@xxxxxxxxx> wrote:
> On Fri, Jan 31, 2014 at 2:22 PM, Guy Harris <guy@xxxxxxxxxxxx> wrote:
>>
>> On Jan 31, 2014, at 10:26 AM, Evan Huus <eapache@xxxxxxxxx> wrote:
>>
>>> On Fri, Jan 31, 2014 at 12:44 PM, Guy Harris <guy@xxxxxxxxxxxx> wrote:
>>>>
>>>> On Jan 31, 2014, at 2:22 AM, Roland Knall <rknall@xxxxxxxxx> wrote:
>>>>
>>>>> But one clarification. You do not check-out a project with git. This
>>>>> is a misconception. You clone the complete repository of wireshark
>>>>> into a local copy.
>>>>
>>>> Unfortunately, yes, that's what happens, imposing a requirement to push changes after they're committed, and adding an extra step to my workflow with no obvious benefit either to me or to the project.
>>>>
>>>> I have, occasionally, been tempted to see whether I could do my own set of porcelain that allows me to completely ignore the "you have your own separate repository" stuff, with a more CVS/SVN-like model, where
>>>>
>>>>        1) there's an "update" operation that grabs from the master changes made since the last time a checkout or update was done, attempts to merge them into the files you have modified, and keeps track of the ones where there was a merge conflict;
>>>
>>> "git pull"
>>
>> ...which refuses to do the pull if there are any files differing from the checked-in versions, so, for me, the operation is actually
>>
>>         git stash; git pull; git stash apply
>>
>> which is in ~/bin/git-update so I can just do "git update".
>>
>>>>        2) there's a "commit" operation that sends your changes to the master;
>>>
>>> "git pull && git commit -a && git push"
>>>
>>> with the caveat that the push should be to gerrit, not straight to master
>>
>> (The caveat being, of course, Wireshark-specific; it's not the only project using Git with which I'm involved.
>>
>> And the caveat needs to be automated in some fashion, whether it's a ~/bin/git-checkin script that does all of the above or a way to configure Git so that pulls come from the master and pushes go to Gerrit.
>>
>> And the "git pull" would, of course, have to be replaced by "git stash; git pull; git stash apply", as per the above.)
>>
>>>>        3) changes are either committed to the master or they're not - there's no notion of adding a file that's already in the repository to a change set, and the "diff" operation shows the difference between all your changes and the master.
>>>
>>> As long as you use "git commit -a" this is basically already true
>>> (with the exception adding new files or removing old files from the
>>> repo).
>>
>> ...and as long as Git doesn't commit anything itself as a result of any of the aforementioned operations.
>>
>>> The ability to manage many small changes is a motivator for the
>>> branching design, though this is perhaps less obvious. Consider a
>>> situation where you may have several changes under development/review
>>> at once, on a large project like the kernel (or Wireshark, for that
>>> matter). In SVN you would probably just have a separate working dir
>>> for each. Pros are extremely fast switching between environments (just
>>> a 'cd' and you're done). Cons are disk space usage,
>>
>> Not a *huge* problem for me, personally.  (Most of the disk space on my laptop is, I think, taken up by a pile of virtual machines.)
>>
>>> and it is
>>> expensive to set up another change (since it requires copying/building
>>> the whole project, which is slow).
>>
>> Not too painful on my machine, either.
>>
>>> The other option is to keep all changes in one working directory and
>>> let users switch between them. Pros are much-reduced disk space, and
>>> near-instantaneous creation/deletion of branches. The con is that it
>>> takes slightly longer to switch branches since doing so requires a
>>> partial rebuild. However when the branches are closely related the
>>> rebuild cost is usually a tiny fraction of the cost to rebuild the
>>> whole project.
>>
>> The other con is that it's the moral equivalent of tabbed browsing, which I, at least, *really hate*, as it keeps a bunch of unrelated things in the same space.  (As per an earlier comment of mine, if Safari had an option to prevent it from even accidentally creating a tab, I would enable it in a heartbeat.)
>>
>> And does that work if your work is not committed until it's time to push to the official repository?  If not, it's another case of Git strongly pushing a particular workflow....
>>
>>> If you only ever work on one change at a time in a given working directory, and
>>> you always push that change before starting another one, then there's
>>> no reason to use branches.
>>
>> That's exactly my workflow, so there's no reason for me to use branches.
>
> There is, I think, one more workaround required for this to be true,
> though this one is due to Gerrit's cherry-picking behaviour, not git
> proper. *sigh*.
>
> If you make a commit and push it to gerrit, then submit that change,
> the SHA of the final merged commit will be different from the SHA you
> pushed because Gerrit amends the commit to add information about the
> review process. This means when you pull git will see two commits with
> identical changes but different SHAs and merge them (the merge will be
> successful since the changes are exactly the same). You will then have
> to reset to origin/master in order to discard the useless duplicate
> commit and merge.

Additional follow-up to the above: I realized that if you do the reset
first then you don't have to deal with the merge at all, so things are
slightly simpler.

> So if you have git-review installed, the commit step actually works out to:
>
> $ git stash && git pull && git stash apply && git commit -a && git review
>
> # submit the change on gerrit
>
> $ git stash && git pull --no-edit && git reset --hard origin/master &&
> git stash apply

So this becomes instead:
$ git stash && git reset --hard origin/master && git pull && git stash apply

Note also that this should be safe even if you're not doing it after a
gerrit review, so you can put it in your ~/bin/git-update script. It
will drop any *commits* not yet upstreamed, but since you're working
one-at-a-time there should never be any of those.

> # caveat, adjusting the argument to git reset as appropriate if
> working on master-1.10 or master-1.8 instead of master.
>
> "Beware of bugs in the above code; I have only proved it correct, not
> tried it." --Knuth

Caveat and disclaimer still apply.