lmi
[Top][All Lists]
Advanced

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

Re: [lmi] [lmi-commits] valyuta/002 18ab8be 5/5: Oops


From: Greg Chicares
Subject: Re: [lmi] [lmi-commits] valyuta/002 18ab8be 5/5: Oops
Date: Sun, 20 Sep 2020 22:37:51 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0

On 2020-09-20 21:01, Vadim Zeitlin wrote:
> On Sun, 20 Sep 2020 20:32:50 +0000 Greg Chicares <gchicares@sbcglobal.net> 
> wrote:
> 
> GC> Two points:
> GC> 
> GC> (1) I attempted it this way, without even thinking...
> GC> 
> GC>   /opt/lmi/src/lmi[0]$git rebase --interactive 
> GC>   There is no tracking information for the current branch.
> GC>   Please specify which branch you want to rebase against.
> GC>   See git-rebase(1) for details.
> GC>       git rebase '<branch>'
> GC>   If you wish to set tracking information for this branch you can do so 
> with:
> GC>       git branch --set-upstream-to=<remote>/<branch> valyuta/002
> GC> 
> GC> ...and the '--set-upstream-to' documentation seemed
> GC> abstruse enough to persuade me to sidestep the issue.
> 
>  I didn't look at the documentation, but the concept is rather simple, as
> usual it's just complicated by using Git-specific terminology: "tracking"
> or "upstream" branch is just the remote branch (i.e. the branch on a
> machine you push to/pull from) that your local branch corresponds to.
> Typically, when pushing your branch to the server the first time you would
> use "--set-upstream" (short: "-u") option to also set the branch you're
> pushing to as the upstream branch, e.g. I typically do
> 
>       $ git push -u origin HEAD
> 
> from my work branch. If you didn't do it when pushing the first time, you
> can do it when pushing the next time or without pushing at all by doing
> what Git suggests above, i.e.
> 
>       $ git branch --set-upstream-to=origin/valyuta/002

Thanks. I've copied and pasted that last command and pressed Enter,
and lived to tell the tale, so I guess all is good. Moving on...

> GC> (2) More important: is it really safe?
> 
>  It's definitely safe to rewrite any commits that haven't been pushed
> anywhere, as nobody is aware of their existence anyhow and so can't
> reference their SHA-1s (unless they've discovered a working quantum
> computer). The danger of rebasing is that it changes the hashes of the
> existing commits, making them different from the one recorded elsewhere.
> But if there are no references to a commit anywhere else, you're completely
> free to rewrite it as much as you want.

Yes, and I do that habitually when working on 'master':
queue up a series of fairly well tested commits, then
before pushing:
 - test comprehensively, and address any revealed errors
   by changing local history so that I never made those
   mistakes; then
 - review all the commits, and make any refinements that
   may occur to me as fixup commits, running an interactive
   rebase to meld the fixups into the original commits;
 - retest, comprehensively; repeat above steps as necessary;
and then finally push. So I'm quite comfortable with
rewriting unpushed history. I'm just afraid to do it in
this case because the referenced online discussion is scary.

> GC> I wrote this in 'gwc/develop1.txt':
> GC> 
> GC>     # to transplant already-pushed commits to a new branch
> GC>   git branch odd/foo
> GC>   git reset --keep origin/master
> GC>     # ...and don't ever rebase that new branch
> 
>  I don't think this does what the comments suggest... I think the comments
> are wrong, because they don't make much sense: why would you want to
> transplant already pushed commits anywhere? But I could be missing
> something here, so could you please explain what exactly are you trying to
> do? My current best guess is that you meant "to transplant changes already
> committed to master (but _not_ pushed yet) to a new branch", but I'm afraid
> of second-guessing you wrongly.

Yes, that's exactly what I meant:

-  # to transplant already-pushed commits to a new branch
+  # to transplant unpushed commits to a new branch

> GC> IIRC, I was just trying to distill a copy-and-paste-able recipe from
> GC> this discussion:
> GC> 
> GC> 
> https://stackoverflow.com/questions/1628563/move-the-most-recent-commits-to-a-new-branch-with-git
> GC> 
> GC> and was alarmed by:
> GC> 
> GC> | WARNING: With Git version 2.0 and later, if you later git rebase the new
> GC> | branch upon the original (master) branch, you may need an explicit
> GC> | --no-fork-point option during the rebase to avoid losing the 
> carried-over
> GC> | commits. Having branch.autosetuprebase always set makes this more 
> likely.
> GC> 
> GC> | Most previous answers are dangerously wrong!
> GC> |
> GC> | Do NOT do this:
> GC> |
> GC> | git branch -t newbranch
> GC> | git reset --hard HEAD~3
> GC> | git checkout newbranch
> GC> |
> GC> | As the next time you run git rebase (or git pull --rebase) those 3
> GC> | commits would be silently discarded from newbranch!
> 
>  This is an interesting point and one I wasn't actually aware about, so
> thanks for letting me know. However it isn't really relevant here: first of
> all, you hadn't done any "git reset" on master after forking valyuta/002

Mais si, I did reset master immediately after:

-  # to transplant already-pushed commits to a new branch
+  # to transplant unpushed commits to a new branch
 git branch odd/foo
 git reset --keep origin/master
   # ...and don't ever rebase that new branch

In addition to that commentary change, should I also do the following?

-  # ...and don't ever rebase that new branch
+  git push --set-upstream origin odd/foo

But perhaps a wholesale replacement of that little block is wanted,
so let me state exactly what I'm trying to accomplish. Sometimes
when I'm on 'master' I'll make a few commits, and then decide that
those commits should be on a brand-new branch instead, leaving
'master' as it was before any of those (unpushed) commits. With
sufficient forethought, I might have anticipated that before
committing anything, but I didn't; and I'm sure git provides a way
for me to make it look like I had foreseen that. As that online
discussion says:

| You want to go back to C, and move D and E to the new branch. Here's what it 
looks like at first:
| 
| A-B-C-D-E (HEAD)
|         ↑
|       master
| 
| After git branch newBranch:
| 
|     newBranch
|         ↓
| A-B-C-D-E (HEAD)
|         ↑
|       master
| 
| After git reset --hard HEAD~2:
| 
|     newBranch
|         ↓
| A-B-C-D-E (HEAD)
|     ↑
|   master

But the discussants debate about the 'git reset' part goes way
over my head. What should the recipe be? I'm thinking of these
three lines:

[1]  git branch odd/foo
[2]  git reset --keep origin/master
[3]  git push --set-upstream origin odd/foo

[1] I'm pretty sure of this, but maybe I'm missing some option.
For a branch like valyuta/002 that is intended to persist for
a long time and be modified many times, would
  git branch --track odd/foo
be better? Would
  git branch --set-upstream-to=origin/odd/foo odd/foo
be better (though repeating the new branch name seems icky),
or does
  git branch --track odd/foo
do the same thing, automatically setting upstream to
the most sensible thing ("origin/new/branch-name"), which
is what I believe I'd always want?

[2] This git-reset command seems to be the crux of that
online discussion, which I still fail to understand.
Out of fear that "git reset --hard" would obliterate my
latest commits, I chose "git reset --keep". What I want,
of course, is that those latest commits be preserved in
odd/foo but removed from master. Reading the git-reset
documentation leads me to think that '--keep' is exactly
right in this case, but I worry that more online
discussions suggest '--hard' and '--keep' seems exotic.

[Of course, I could
-  git reset --SOME_OPTION origin/master
+  git reset --SOME_OPTION HEAD~4
or whatever; I do understand that last argument and
would edit it when using this recipe.]  

[3] Is '--set-upstream' unnecessary here if [1] specifies
'--track'?

Tying all those conjectures together, should the recipe
ideally be as follows?

  git branch --track odd/foo
  git reset --keep origin/master
  git push origin odd/foo

> from it, AFAIK. Second, you're not rebasing on master anyhow (this would be
> bad as it would change the hashes of all commits already pushed to
> origin/valyuta/002), so you're not affected by this issue.

Well...I had thought of trying that, after making some
changes in master, but realized how awful that could be.
I'm getting comfortable with branching (no small
accomplishment), but merging is inherently awful. It
doesn't matter that git does some pretty smart things
to resolve merge conflicts; conflicts still arise, and
are always hard to deal with.

My plan instead is to let 'valyuta' evolve until I'm
satisfied with it, and then construct and commit (to
master) the series of changes that I would have made
if I had thought through everything first, perfectly.
So Athena still emerges fully mature from Zeus's skull,
but the public doesn't see how sausages are made.

> Third, according
> to my git-rebase(1):
> 
>       If either <upstream> or --root is given on the command line, then
>       the default is --no-fork-point

I can parse that as an English sentence, but I still
have no idea what it means. But I can understand yours:

> so if you specify the <upstream> to rebase upon explicitly, the problem
> can't happen anyhow, and it's probably a good practice to be explicit for
> all non-interactive rebases unless you're absolutely sure what you're
> doing.

Excellent. I'll do that then, with '--track' or whatever
as discussed above, for future work. And for the existing
branch:

> GC> So should I just
> GC>   git branch --set-upstream-to= valyuta/002
> 
>  Note that you need to use --set-upstream-to=origin/valyuta/002 here, you
> can't set a branch as its own upstream (and Git will just ignore your
> attempt to do it if you try).

Okay, I did this:

git branch --set-upstream-to=origin/valyuta/002



reply via email to

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