lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Help combining git branches


From: Greg Chicares
Subject: Re: [lmi] Help combining git branches
Date: Thu, 1 Oct 2020 13:35:05 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0

On 2020-09-29 17:53, Vadim Zeitlin wrote:
> On Tue, 29 Sep 2020 15:55:36 +0000 Greg Chicares <gchicares@sbcglobal.net> 
> wrote:
> 
> GC> On 2020-09-20 23:24, Vadim Zeitlin wrote:
[...]
> GC> >    to note that you shouldn't rebase this branch on master without using
> GC> >    either an explicit branch name or --no-fork-point explicitly (you 
> don't
> GC> >    have to document both ways, just choose one you like best and it will
> GC> >    be enough).
> GC> 
> GC> I just realized that I don't understand what you said. To rebase
> GC> branch A on branch B, I should think it's necessary to name them
> GC> both...so mustn't both branch names always be explicitly specified?
> 
>  No, the syntax for the usual form of git-rebase is
> 
>       git rebase [options] [<upstream> [<branch]]
> 
> i.e. both branch names are optional and it's, in fact, pretty common to
> omit the latter one because doing this just means rebasing the current
> branch. It's less common, IME, to omit <upstream>, but it still can be done
> and then the default upstream configured for the current branch (remember
> "git push --set-upstream"?) will be used.

Okay, thanks for clarifying that, because I was really stuck on that point.

> GC>  - I added branch valyuta/002;
> GC>  - valyuta commits are carelessly casual; eventually, I'll want many
> GC>    of their ultimate effects on master, but I'm sure I'll never want
> GC>    their twisted history on master; and
> GC>  - I've made changes there and to master, so they've diverged.
> GC> Now there are some commits on master that I want on the branch (for
> GC> pc-linux-gnu support).
[...]
> GC> The first thing I tried was:
> GC> 
> GC> $git switch valyuta/002
> GC> Switched to branch 'valyuta/002'
> GC> Your branch is up to date with 'origin/valyuta/002'.
> GC> $git rebase --no-fork-point master
> 
>  As you've noticed yourself below, "--no-fork-point" here is superfluous,
> even if harmless.
> 
> GC> Applying: Change type of currency variables to 'currency' in headers
> GC> Applying: Currency
> GC> Using index info to reconstruct a base tree...
> GC> M       ihs_acctval.cpp
> GC> M       ihs_avmly.cpp
> GC> M       ihs_avsolve.cpp
> GC> Falling back to patching base and 3-way merge...
> GC> Auto-merging ihs_avsolve.cpp
> GC> CONFLICT (content): Merge conflict in ihs_avsolve.cpp
[...snip a couple other conflicts...]
> GC> error: Failed to merge in the changes.
> GC> Patch failed at 0002 Currency
> GC> hint: Use 'git am --show-current-patch' to see the failed patch
> GC> 
> GC> ...and already I'm in the Twilight Zone.
> 
>  It's not really surprising that there are conflicts

What astonished me was not that there were conflicts, but that
git seemed to be telling me that I could resolve them only by
editing an enormous single patch file...

> GC> The first of about forty commits came through okay, but the second
> GC> failed, and all I have to work with is a monolithic patch file.
> 
>  No, it's just Git not being very helpful (although I admit I never
> realized how confusing this hint could be before reading your message).
That's exactly what I was missing, because
  "hint: Use 'git am --show-current-patch' to see the failed patch"
seemed to be suggesting that I didn't have the option of editing
the individual files to resolve the conflicts.

> [useless, as you already did this below, section kept for reference]

Quite useful, actually...

>  If you open ihs_avsolve.cpp in Vim, for example, and search for
> "^[<=>]\{7\}\( \|$\)" (without quotes),

...because that's so handy. I had been searching for "<<<", and never
thought of searching for all the markers at once--which, at least with
my ~/.vimrc, causes them all to be highlighted, making the work easier.

>  In this case it should be pretty simple, as the changes in valyuta branch
> are superficial, i.e. you should just take the master version and then add
> .c() or whatever is needed to them.

I didn't have to add any ".c()"; I guess git automerged everything it
could, and left only three small hunks to me.

> GC> Maybe I could handle that for one commit, but not for forty,

[Misled by
  "hint: Use 'git am --show-current-patch' to see the failed patch"
, I recoiled from the thought of editing forty monolithic patch files.]

>  I don't think you're going to get the same conflict again, but if you do,
> I'd like to mention that there is a very useful (but somewhat surprising,
> which is why it's turned off by default, I guess) git command with an
> extremely clear name "rerere". In fact, expanding its name to "reuse
> recorded resolution [of conflicted merges]" probably doesn't make it much
> more clear. But using it is very simple: just run "git rerere" (without any
> arguments) once and Git will remember your merge conflict resolutions. This
> means that when/if you need to resolve the same conflict again as Git will
> automatically apply the same resolution to it. This is a bit confusing
> because it will still tell you about the conflict, but then there won't be
> any conflicts when you look at the file. But it's also, of course, very
> useful, because you won't need to apply the same resolution manually again.

Thanks, I had heard of that command, but never looked into it. It's
much easier to understand it when faced with a situation where it
might be used to advantage.

However, in this case, the changes were so small that it was no
trouble to repeat them. And playing them back through my fingers,
from memory, led me to notice one hunk where both branches were
improved, in different ways. The first time through, I had hastily
chosen one. The second time, I chose the best of both.

> GC> After aborting again, I try '--onto' because it sounds like it would
> GC> be perfect for my purposes, according to this diagram:
> GC> 
> GC> 
> https://stackoverflow.com/questions/33942588/difference-between-rebase-master-and-rebase-onto-master-from-a-branch-deri/33942992#33942992
[...]
> GC> First, rewinding head to replay your work on top of it...
> GC> 
> GC> I was surprised that it just stopped there,
> 
>  Yes, me too... If I do it here, it says
> 
>       Successfully rebased and updated refs/heads/valyuta/002.
> 
>  Let's try to understand what it's supposed to do: git-rebase starts by
> stashing (not using git-stash, but using a similar mechanism) all changes
> between <upstream> and <branch>. In your case, there are _no_ such changes
> because your branch is the same as its upstream origin/valyuta/002, as
> shown by "git switch" output in your email.
> 
>  Next it resets the branch head to "master", because you've used "--onto
> master". And finally it reapplies all the stashed changes on master --
> except that there are none, so it doesn't actually do anything.
> 
>  IOW the effect of "git rebase --onto master" when your branch is
> synchronized with its upstream is just to make your branch the same as
> master. Which is almost surely not something you'd like to do.

How very droll.

> GC> $git pull --no-ff
> 
>  FWIW I still recommend not using pull to do merges implicitly. I.e.
> instead of the above I'd do
> 
>       $ git fetch
>       $ git merge origin/valyuta/002
> 
> which is exactly the same thing, but more clear.

Okay, here, you recommend an alternative to 'git pull --no-ff'.
I feel certain that you've told me that before, and that I'd
memorialized that advice in 'gwc/develop1.txt', but I hadn't;
instead I find only this:

|   # Update the local source tree (where I make my own changes) when
|   # someone else has committed a change to the online master repo.
|
| git remote -v update
| git pull
|
|   # If that yields "fatal: Not possible to fast-forward, aborting":
|
| git pull --rebase

Would you recommend the same fetch-and-merge as an alternative
to 'git pull --rebase' there?

>  FWIW the best would have probably been to just return to your original
> valyuta/002 state, i.e. "git reset --keep origin/valyuta/002", and then
> redo "git merge master" (or origin/master if it's different from your local
> master, but I think they're the same). Unfortunately right now this means
> that you'd have to re-resolve the same conflicts again because you hadn't
> enabled rerere, so it's not worth doing it. But this is how it would
> normally be done for a long-lived branch like this.

That's what I've now done with that branch.


reply via email to

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