* git-reset and clones
@ 2006-03-16 14:34 Paul Jakma
[not found] ` <20060316095213.2a8f650a.seanlkml@sympatico.ca>
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Paul Jakma @ 2006-03-16 14:34 UTC (permalink / raw)
To: git list
Hi,
Next dumb question:
If a git repository has a reset HEAD~X done, then any later pulls in
clone repositories get /really/ upset, with:
$ git pull
* refs/heads/origin: does not fast forward to branch 'master' of
/home/paul/foo-git/;
Type of thing. This seems to be a similar issue to:
http://www.gelato.unsw.edu.au/archives/git/0510/10767.html
The question is has this improved at all since last year? Is there
anything the origin repository maintainer (the one who did reset) can
do to recover from this?
I'm guessing the answer is:
Yes:
1. where git-reset has already been done, manually update the
refs back to the previous HEAD
2. then use git-revert, and continue to use git-revert only.
My question then would be, presuming some innocent repository
maintainer has already done 1, what's the easiest way to accomplish
1?
(they shouldn't have done it obviously, but assume they're git
newbies, made an honest mistake and now need to recover, preferably
without having to involve those who pull).
regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
Fortune:
Be cautious in your daily affairs.
^ permalink raw reply [flat|nested] 12+ messages in thread[parent not found: <20060316095213.2a8f650a.seanlkml@sympatico.ca>]
* Re: git-reset and clones [not found] ` <20060316095213.2a8f650a.seanlkml@sympatico.ca> @ 2006-03-16 14:52 ` sean 2006-03-16 15:48 ` Paul Jakma 0 siblings, 1 reply; 12+ messages in thread From: sean @ 2006-03-16 14:52 UTC (permalink / raw) To: Paul Jakma; +Cc: git On Thu, 16 Mar 2006 14:34:42 +0000 (GMT) Paul Jakma <paul@clubi.ie> wrote: > If a git repository has a reset HEAD~X done, then any later pulls in > clone repositories get /really/ upset, with: > > $ git pull > * refs/heads/origin: does not fast forward to branch 'master' of > /home/paul/foo-git/; > > Type of thing. This seems to be a similar issue to: > > http://www.gelato.unsw.edu.au/archives/git/0510/10767.html > > The question is has this improved at all since last year? Is there > anything the origin repository maintainer (the one who did reset) can > do to recover from this? It's still not a recommended operation on a repository that is pulled by others. If you realize you made a mistake by resetting the head, you can undo the operation afterward with: $ git reset ORIG_HEAD Sean ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-16 14:52 ` sean @ 2006-03-16 15:48 ` Paul Jakma 0 siblings, 0 replies; 12+ messages in thread From: Paul Jakma @ 2006-03-16 15:48 UTC (permalink / raw) To: sean; +Cc: git On Thu, 16 Mar 2006, sean wrote: > $ git reset ORIG_HEAD Ah, of course :). Thanks. regards, -- Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A Fortune: There's no such thing as pure pleasure; some anxiety always goes with it. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-16 14:34 git-reset and clones Paul Jakma [not found] ` <20060316095213.2a8f650a.seanlkml@sympatico.ca> @ 2006-03-16 14:53 ` Andreas Ericsson 2006-03-16 14:59 ` Andreas Ericsson [not found] ` <20060316102145.35294eed.seanlkml@sympatico.ca> 2006-03-17 2:10 ` Junio C Hamano 2 siblings, 2 replies; 12+ messages in thread From: Andreas Ericsson @ 2006-03-16 14:53 UTC (permalink / raw) To: Paul Jakma; +Cc: git list Paul Jakma wrote: > Hi, > > Next dumb question: > > If a git repository has a reset HEAD~X done, then any later pulls in > clone repositories get /really/ upset, with: > > $ git pull > * refs/heads/origin: does not fast forward to branch 'master' of > /home/paul/foo-git/; > > Type of thing. This seems to be a similar issue to: > > http://www.gelato.unsw.edu.au/archives/git/0510/10767.html > > The question is has this improved at all since last year? Is there > anything the origin repository maintainer (the one who did reset) can do > to recover from this? > > I'm guessing the answer is: > > Yes: > > 1. where git-reset has already been done, manually update the > refs back to the previous HEAD > 2. then use git-revert, and continue to use git-revert only. > > My question then would be, presuming some innocent repository maintainer > has already done 1, what's the easiest way to accomplish 1? > > (they shouldn't have done it obviously, but assume they're git newbies, > made an honest mistake and now need to recover, preferably without > having to involve those who pull). > I *think* this should work. Get a backup before trying. Note that I'm assuming "git reset" hasn't been run several times, or you'll have to replace ORIGIN with whatever HEAD pointed to before the first reset. In mothership-repo: git checkout master git branch next-master ORIGIN git rebase next-master; # fix conflicts and commit git branch -d master git checkout -b master next-master git -d next-master git revert (the bad commits) Some shortcuts can be taken if we're not to use git commands the entire way, but this is easier to explain to those newbie-ish people you mentioned. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-16 14:53 ` Andreas Ericsson @ 2006-03-16 14:59 ` Andreas Ericsson [not found] ` <20060316102145.35294eed.seanlkml@sympatico.ca> 1 sibling, 0 replies; 12+ messages in thread From: Andreas Ericsson @ 2006-03-16 14:59 UTC (permalink / raw) To: Andreas Ericsson; +Cc: Paul Jakma, git list Andreas Ericsson wrote: > > git branch next-master ORIGIN s/ORIGIN/ORIG_HEAD/ otherwise the advice still applies. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <20060316102145.35294eed.seanlkml@sympatico.ca>]
* Re: git-reset and clones [not found] ` <20060316102145.35294eed.seanlkml@sympatico.ca> @ 2006-03-16 15:21 ` sean 0 siblings, 0 replies; 12+ messages in thread From: sean @ 2006-03-16 15:21 UTC (permalink / raw) To: Andreas Ericsson; +Cc: paul, git On Thu, 16 Mar 2006 15:53:56 +0100 Andreas Ericsson <ae@op5.se> wrote: > In mothership-repo: > git checkout master > git branch next-master ORIGIN > git rebase next-master; # fix conflicts and commit > git branch -d master > git checkout -b master next-master > git -d next-master > git revert (the bad commits) Downstream repos may still be broken afterward though; not much you can do about that unfortunately. Sean ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-16 14:34 git-reset and clones Paul Jakma [not found] ` <20060316095213.2a8f650a.seanlkml@sympatico.ca> 2006-03-16 14:53 ` Andreas Ericsson @ 2006-03-17 2:10 ` Junio C Hamano 2006-03-17 19:19 ` Jon Loeliger 2006-03-19 21:40 ` Petr Baudis 2 siblings, 2 replies; 12+ messages in thread From: Junio C Hamano @ 2006-03-17 2:10 UTC (permalink / raw) To: paul; +Cc: git list Paul Jakma <paul@clubi.ie> writes: > If a git repository has a reset HEAD~X done, then any later pulls in > clone repositories get /really/ upset, with: > > $ git pull > * refs/heads/origin: does not fast forward to branch 'master' of > /home/paul/foo-git/; > > Type of thing. This seems to be a similar issue to: > > http://www.gelato.unsw.edu.au/archives/git/0510/10767.html > > The question is has this improved at all since last year? Is there > anything the origin repository maintainer (the one who did reset) can > do to recover from this? You used to have something like this: o---o---o---A / ^ your HEAD used to point at here ---o---o---o and you forgot other people already have the commit chain up to commit A. But you rewound and did cleanups: o---o---o---A / ---o---o---o---o---o---B ^ your HEAD now points at here People who track your HEAD have A and your updated head B does not fast forward. Oops. The recovery consists of two steps. The first step is more important. To find what commits you lost that others already may have. You may be lucky and remember A's commit object name, but when I did that I had to ask around on the list X-<. The second step is a single command: $ git merge -s ours 'Graft the lost side branch back in' \ HEAD A where A is the object name of that commit. On your current branch, this creates a merge commit between A and B (your current HEAD), taking the tree object from B. o---o---o---A / \ ---o---o---o---o---o---B---M You want to keep the contents of the cleaned-up HEAD, so that is why you are taking the tree from B. With this commit M, you are telling the outside world that it is OK if they start from a commit on the now-recovered side branch. If the tree of A and B exactly match, further merges with people starting from A branch would not have conflicts. If the difference between A and B are mostly clean-ups, automerge would lose dirtiness you cleaned-up when they update to your new HEAD (because the transition from A to M reverts the dirtiness, which is what your clean-up was about), which is what you want. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-17 2:10 ` Junio C Hamano @ 2006-03-17 19:19 ` Jon Loeliger 2006-03-17 20:39 ` Junio C Hamano 2006-03-17 21:21 ` Andreas Ericsson 2006-03-19 21:40 ` Petr Baudis 1 sibling, 2 replies; 12+ messages in thread From: Jon Loeliger @ 2006-03-17 19:19 UTC (permalink / raw) To: Junio C Hamano; +Cc: paul, Git List On Thu, 2006-03-16 at 20:10, Junio C Hamano wrote: > > You used to have something like this: > > > o---o---o---A > / ^ your HEAD used to point at here > ---o---o---o > > and you forgot other people already have the commit chain up to > commit A. But you rewound and did cleanups: > > o---o---o---A > / > ---o---o---o---o---o---B > ^ your HEAD now points at here > > People who track your HEAD have A and your updated head B does > not fast forward. Oops. > > The recovery consists of two steps. The first step is more > important. To find what commits you lost that others already > may have. You may be lucky and remember A's commit object name, > but when I did that I had to ask around on the list X-<. > > The second step is a single command: > > $ git merge -s ours 'Graft the lost side branch back in' \ > HEAD A > > where A is the object name of that commit. On your current > branch, this creates a merge commit between A and B (your > current HEAD), taking the tree object from B. > > o---o---o---A > / \ > ---o---o---o---o---o---B---M Junio, Can you explain a bit more why the "ours" strategy comes into play here? I _think_ I understand, but I'd like to hear a bit more explanation, please. How is this different from just merging in A directly? > You want to keep the contents of the cleaned-up HEAD, so that is > why you are taking the tree from B. And the "ours" strategy effectively says, "Favor the B side of things when pulling in the A parts", right? > With this commit M, you are > telling the outside world that it is OK if they start from a > commit on the now-recovered side branch. This is mystical to me. How is the "A" (ie, side branch) now in a "recovered" state? Thanks, jdl ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-17 19:19 ` Jon Loeliger @ 2006-03-17 20:39 ` Junio C Hamano 2006-03-17 21:00 ` Jon Loeliger 2006-03-17 21:21 ` Andreas Ericsson 1 sibling, 1 reply; 12+ messages in thread From: Junio C Hamano @ 2006-03-17 20:39 UTC (permalink / raw) To: Jon Loeliger; +Cc: paul, Git List Jon Loeliger <jdl@freescale.com> writes: >> ... On your current >> branch, this creates a merge commit between A and B (your >> current HEAD), taking the tree object from B. >> >> o---o---o---A >> / \ >> ---o---o---o---o---o---B---M > > Can you explain a bit more why the "ours" strategy > comes into play here? I _think_ I understand, but > I'd like to hear a bit more explanation, please. > How is this different from just merging in A directly? >> You want to keep the contents of the cleaned-up HEAD, so that is >> why you are taking the tree from B. > > And the "ours" strategy effectively says, "Favor the B > side of things when pulling in the A parts", right? Yes, it is stronger than that. "ours" says: "the tree from our head commit B *is* the resulting tree -- whatever we are merging into us does not matter". >> With this commit M, you are >> telling the outside world that it is OK if they start from a >> commit on the now-recovered side branch. > > This is mystical to me. How is the "A" (ie, side branch) > now in a "recovered" state? Although their effects are superseded (B^{tree} == M^{tree}), they are still in the ancestry chain. To a downstream person who were lucky enough not to have made commits on A yet, next pull from you would have involved merging B and A. If the upstream did not do the magic "ours" merge, the git-fetch step would refuse to update the remote tracking branch head, so the downstream person needs to force the fetch. After forcing the fetch, the merge would have involved resolving the conflicts coming from 3-way merge in this: o---o---o---A---N / / ---o---o---o---o---o---B---' Because the forked track leading to B was either to fix mistakes or clean things up the upstream originally did in the track leading to A, the commits on the tracks leading to A and B from their fork point are almost guaranteed to have conflicting changes, and resolution of that conflict is forced on the downstream person. Worse yet, from this point on, since the upstream discarded the track that contains A, the branch downstream person has will _never_ converge to upstream branch, even though the downstream person did _no_ development of his own in the meantime. This is *B*A*D*. If there is a magic "ours" merge, the downstream person's repository records A as the last tip on the tracking branch, and git-fetch sees the updated head M is a descendant of it, so it simply fast-forwards: o---o---o---A / \ ---o---o---o---o---o---B---M Now, if the downstream was unlucky and have commits based on A, the story is a bit different, but the principles are the same. Without the "ours" merge M, you will get this: o---o---o---A---X---N / / ---o---o---o---o---o---B-------' When creating the merge N, even if the change between A and X (i.e. the downstream's own work) does not touch the paths that differ between A and B, the downstream is forced to resolve conflicts between A and B. This is unnecessary burden for him. The upstream should have cleaned up his own mess. With the "ours" merge M, you will get this: o---o---o---A---X---N / \ / ---o---o---o---o---o---B---M---' The downstream does not need to worry about the conflicts between A and B. It has been already resolved at M. Especially, if the change between A and X does not touch the paths that differ in A and B, conflict resolution would be purely about his own work. In either case, since the downstream has his own development, the heads of their branches never converge until the upstream buys his changes (i.e. pull from the downstream that has "N" commit), but that is not a problem but a feature and does not have anything to do with this "oops, rewound by mistake" issue. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-17 20:39 ` Junio C Hamano @ 2006-03-17 21:00 ` Jon Loeliger 0 siblings, 0 replies; 12+ messages in thread From: Jon Loeliger @ 2006-03-17 21:00 UTC (permalink / raw) To: Junio C Hamano; +Cc: paul, Git List On Fri, 2006-03-17 at 14:39, Junio C Hamano wrote: > > And the "ours" strategy effectively says, "Favor the B > > side of things when pulling in the A parts", right? > > Yes, it is stronger than that. "ours" says: "the tree from our > head commit B *is* the resulting tree -- whatever we are merging > into us does not matter". Aha! This all makes much more sense now suddenly. Thank you. > > o---o---o---A---N > / / > ---o---o---o---o---o---B---' > > Because the forked track leading to B was either to fix mistakes > or clean things up the upstream originally did in the track > leading to A, the commits on the tracks leading to A and B from > their fork point are almost guaranteed to have conflicting > changes, and resolution of that conflict is forced on the > downstream person. Worse yet, from this point on, since the > upstream discarded the track that contains A, the branch > downstream person has will _never_ converge to upstream branch, > even though the downstream person did _no_ development of his > own in the meantime. This is *B*A*D*. Wow. Yeah. Bad. > If there is a magic "ours" merge, the downstream person's > repository records A as the last tip on the tracking branch, and > git-fetch sees the updated head M is a descendant of it, so it > simply fast-forwards: That's beautiful. I get it. This has been an extraordinarily helpful explanation (for me)! Thank you! jdl ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-17 19:19 ` Jon Loeliger 2006-03-17 20:39 ` Junio C Hamano @ 2006-03-17 21:21 ` Andreas Ericsson 1 sibling, 0 replies; 12+ messages in thread From: Andreas Ericsson @ 2006-03-17 21:21 UTC (permalink / raw) To: Jon Loeliger; +Cc: Junio C Hamano, paul, Git List I'm in sort of shallow waters, hoping that Junio or Linus will come along and pull me off the shores in case I mis-step and say something stupid that would have made an amusing pictograph had it been done right by a cartoonist. Jon Loeliger wrote: > On Thu, 2006-03-16 at 20:10, Junio C Hamano wrote: > > >>You used to have something like this: >> >> >> o---o---o---A >> / ^ your HEAD used to point at here >> ---o---o---o >> >>and you forgot other people already have the commit chain up to >>commit A. But you rewound and did cleanups: >> >> o---o---o---A >> / >> ---o---o---o---o---o---B >> ^ your HEAD now points at here >> >>People who track your HEAD have A and your updated head B does >>not fast forward. Oops. >> >>The recovery consists of two steps. The first step is more >>important. To find what commits you lost that others already >>may have. You may be lucky and remember A's commit object name, >>but when I did that I had to ask around on the list X-<. >> >>The second step is a single command: >> >> $ git merge -s ours 'Graft the lost side branch back in' \ >> HEAD A >> >>where A is the object name of that commit. On your current >>branch, this creates a merge commit between A and B (your >>current HEAD), taking the tree object from B. >> >> o---o---o---A >> / \ >> ---o---o---o---o---o---B---M > > > Junio, > > Can you explain a bit more why the "ours" strategy > comes into play here? I _think_ I understand, but > I'd like to hear a bit more explanation, please. > How is this different from just merging in A directly? > "Ours" is an algorithm you can invent yourself and pass as the defautl merge strategy (useful if you know you'll always keep upstream as-is or some such). > >>You want to keep the contents of the cleaned-up HEAD, so that is >>why you are taking the tree from B. > > > And the "ours" strategy effectively says, "Favor the B > side of things when pulling in the A parts", right? > Yes, and/or no. "Ours"' is still whatever you want it to be. Perhaps we should add some new strategies, like "favour-current" and "favour-new". > >> With this commit M, you are >>telling the outside world that it is OK if they start from a >>commit on the now-recovered side branch. > > > This is mystical to me. How is the "A" (ie, side branch) > now in a "recovered" state? > Because the commits pullers already have are now inside the respository history, as seen by average pullers (again). The merge between "master" (or some such) and "new-devel" (or some such) happen to coincide, which means they share a mutual merge-base, which means they're both part of the same chain of developemnt. If you intend to disimiss most of the changes between (fork-point) and (point-of-new-weird-rebase) this might not be the best solution, but... Sorry, but to me this is friaday night and currently I can't logically differ between a bluewhale and a kangaroo [*1] /exon [1] Sadly, this has been empirically proven. [*2] [2] At some other time. I'm no *that* drunk right now. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: git-reset and clones 2006-03-17 2:10 ` Junio C Hamano 2006-03-17 19:19 ` Jon Loeliger @ 2006-03-19 21:40 ` Petr Baudis 1 sibling, 0 replies; 12+ messages in thread From: Petr Baudis @ 2006-03-19 21:40 UTC (permalink / raw) To: Junio C Hamano; +Cc: paul, git list Dear diary, on Fri, Mar 17, 2006 at 03:10:23AM CET, I got a letter where Junio C Hamano <junkio@cox.net> said that... > You used to have something like this: > > > o---o---o---A > / ^ your HEAD used to point at here > ---o---o---o > > and you forgot other people already have the commit chain up to > commit A. But you rewound and did cleanups: > > o---o---o---A > / > ---o---o---o---o---o---B > ^ your HEAD now points at here > > People who track your HEAD have A and your updated head B does > not fast forward. Oops. Just for the sake of completeness, this is a GIT-only doctrine; Cogito is more confiding and has less strict requirements. First, when fetching, it does not care at all whether the new head is a fast-forward of the original one or not. Second, when the people who are tracking you had A as their current master head _and_ also the origin remote head (or whichever their respective branch names are), their current master head will be updated to B when cg-updating, as Cogito pretends it to be a fast-forward even though it is not. So, in the simple tracking cases, Cogito will do the right thing, if you use cg-update. -- Petr "Pasky" Baudis Stuff: http://pasky.or.cz/ Right now I am having amnesia and deja-vu at the same time. I think I have forgotten this before. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-03-19 21:40 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-16 14:34 git-reset and clones Paul Jakma
[not found] ` <20060316095213.2a8f650a.seanlkml@sympatico.ca>
2006-03-16 14:52 ` sean
2006-03-16 15:48 ` Paul Jakma
2006-03-16 14:53 ` Andreas Ericsson
2006-03-16 14:59 ` Andreas Ericsson
[not found] ` <20060316102145.35294eed.seanlkml@sympatico.ca>
2006-03-16 15:21 ` sean
2006-03-17 2:10 ` Junio C Hamano
2006-03-17 19:19 ` Jon Loeliger
2006-03-17 20:39 ` Junio C Hamano
2006-03-17 21:00 ` Jon Loeliger
2006-03-17 21:21 ` Andreas Ericsson
2006-03-19 21:40 ` Petr Baudis
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).