All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: Why is it bad to rewind a branch that has already been pushed out?
@ 2007-02-03  8:42 linux
  2007-02-03  9:04 ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: linux @ 2007-02-03  8:42 UTC (permalink / raw)
  To: git, junkio

You're quite right that git's basic history model won't get
confused, just the users might be.

The basic problem is that, if you rewind your series from j to j^,
and Alice has already fetched it, she'll get an error when she tries to
fetch it again and git notices that j -> h is not a fast-forward.

It's not the error per se that's the problem, but the potentially
confusing condition that git fetch justifiably refuses to let you
get into without explicit authorization.

Heck, it could be a security breach, which is the main reason that
it's an error and not a warning.

It won't confuse git, but might confuse Alice.

How about:

 Be careful with that last command: in addition to losing any changes
 in the working directory, it will also remove all later commits from
 this branch.  If this branch is the only branch containing those
-commits, they will be lost.  (Also, don't use "git reset" on a
-publicly-visible branch that other developers pull from, as git will
-be confused by history that disappears in this way.)
+commits, they will be lost.  Also, avoid using "git reset" on a
+publicly-visible branch that other developers have pulled from,
+because git (deliberately) has no way to "pull back" the commits
+they've already seen.  Git can cope with the resultant mess, but
+it can be confusing.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-03  8:42 Why is it bad to rewind a branch that has already been pushed out? linux
@ 2007-02-03  9:04 ` Junio C Hamano
  0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2007-02-03  9:04 UTC (permalink / raw)
  To: linux; +Cc: git

linux@horizon.com writes:

> The basic problem is that, if you rewind your series from j to j^,
> and Alice has already fetched it, she'll get an error when she tries to
> fetch it again and git notices that j -> h is not a fast-forward.

Well, if you do a pull without tracking branch, like Linus seems
to do, there is no non-fast-forward error.  Also, repositories
prepared with git-clone from 1.5.0 by default will have tracking
branches of forcing kind.  I.e. the fetch configuration will
specify tracking with '+' in front:

	[remote "origin"]
		fetch = +refs/heads/*:refs/remotes/origin/*

so non-fast-forward check will not trigger in general.

> It won't confuse git, but might confuse Alice.

I think I should have made it more obvious, but the emphasis of
my proposed rewording is not about removing the word "git gets
confused" in order to defend git.

It is very likely to confuse Alice (especially if she did not
have any 'a' commits), having to do the merge.  But I think the
confusion is just a symptom, and the real disease lies
elsewhere.  The real disease is that it is wrong for me to force
the merge on Alice, from the workflow perspective, and that is
true even if we were lucky and Alice did not get confused about
the merge (e.g. 'j' and 'h' series did not have anything
related, and/or 'a' really fixed up 'j').  In any case, Alice
should not to have to worry about what happened between 'j' and
'h' forks, and I think the document should emphasize that point.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-04 16:16 ` Robin Rosenberg
@ 2007-02-04 20:08   ` Junio C Hamano
  0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2007-02-04 20:08 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

Robin Rosenberg <robin.rosenberg.lists@dewire.com> writes:

> Mention git-revert as an alternative to git-reset to revert changes.

Thanks; that makes sense.  Applied.

It is not a biggie but for future reference you might want to
check your KMail configuration to avoid the wrapped line below:

> diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
> index 5fc5be5..129c5c5 100644
> --- a/Documentation/tutorial.txt
> +++ b/Documentation/tutorial.txt
> @@ -461,6 +461,8 @@ this branch.  If this branch is the only branch containing 
> those
>  commits, they will be lost.  Also, don't use "git reset" on a

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-03 19:42   ` Junio C Hamano
@ 2007-02-04 18:01     ` Andy Parkins
  0 siblings, 0 replies; 9+ messages in thread
From: Andy Parkins @ 2007-02-04 18:01 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

On Saturday 2007, February 03 19:42, Junio C Hamano wrote:

> Actually, if you are assuming a, h, and j are unrelated, then
> the merge done by Alice will _not_ revert 'j', so the history
> will perfectly be fine.  The merge result will have a half-baked
> work done with 'j', and everybody can build on top of.

Absolutely true.

Your point is a strong one.  I think I'm still not thinking big enough 
with the distributed development concept.  Your point has made me 
consider that I've been overly concerned about not rebasing pushed 
commits.  Provided you're willing to correct conflicts in a merge; they 
aren't as bad as I initially thought - in fact they offer a further 
choice when creating project history.

Thanks Junio.



Andy
-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE
andyparkins@gmail.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-03  6:40 Junio C Hamano
  2007-02-03 10:40 ` Andy Parkins
  2007-02-03 13:20 ` Theodore Tso
@ 2007-02-04 16:16 ` Robin Rosenberg
  2007-02-04 20:08   ` Junio C Hamano
  2 siblings, 1 reply; 9+ messages in thread
From: Robin Rosenberg @ 2007-02-04 16:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Mention git-revert as an alternative to git-reset to revert changes.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---

diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index 5fc5be5..129c5c5 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -461,6 +461,8 @@ this branch.  If this branch is the only branch containing 
those
 commits, they will be lost.  Also, don't use "git reset" on a
 publicly-visible branch that other developers pull from, as it will
 force needless merges on other developers to clean up the history.
+If you need to undo changes that you have pushed, use gitlink:git-revert[1]
+instead.

 The git grep command can search for strings in any version of your
 project, so

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-03 10:40 ` Andy Parkins
@ 2007-02-03 19:42   ` Junio C Hamano
  2007-02-04 18:01     ` Andy Parkins
  0 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2007-02-03 19:42 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git

Andy Parkins <andyparkins@gmail.com> writes:

> In the following I've assumed that both "h" and "a" commits are 
> independent work, neither of which works on "j" (which isn't quite what 
> you described).  It's not really appropriate for the tutorial, so I 
> haven't really helped you.
> ...
>> (4) Alice pulls from me again:
>>
>> 	---o---o---o---j---a---a---*
>>                   \             /
>>                    h---h---h---h
>>
>> Contrary to the description, git will happily have Alice merge
>> between the two branches, and never gets confused.
>
> The problem is not that the working tree is wrong, it is that the 
> history is wrong.  This sequence of development isn't best represented 
> by a merge.  When we look at the history later, we'll see it as two 
> branches, but that isn't true.
>
> The graph shows that "j" was committed and then probably conflicted 
> in "*" and fixed.  The problem is that you can't point to any non-merge 
> commit that reverted/corrected "j" and explains why that wasn't a good 
> idea - so the "story" that the history tells us is incomplete.  The 
> correction was done just as a conflict resolution in "*".

Actually, if you are assuming a, h, and j are unrelated, then
the merge done by Alice will _not_ revert 'j', so the history
will perfectly be fine.  The merge result will have a half-baked
work done with 'j', and everybody can build on top of.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-03  6:40 Junio C Hamano
  2007-02-03 10:40 ` Andy Parkins
@ 2007-02-03 13:20 ` Theodore Tso
  2007-02-04 16:16 ` Robin Rosenberg
  2 siblings, 0 replies; 9+ messages in thread
From: Theodore Tso @ 2007-02-03 13:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Fri, Feb 02, 2007 at 10:40:49PM -0800, Junio C Hamano wrote:
> I do not think this is a good explanation.  For example, if we
> do this:
> 
> (1) I build a series and push it out.
> 
> 	---o---o---o---j
> 
> (2) Alice clones from me, and builds two commits on top of it.
> 
> 	---o---o---o---j---a---a
> 
> (3) I rewind one and build a few, and push them out.
> 
> 	---o---o---o...j
>                     \
>                      h---h---h---h
> 
> (4) Alice pulls from me again:
> 
> 	---o---o---o---j---a---a---*
>                     \             /
>                      h---h---h---h
> 
> Contrary to the description, git will happily have Alice merge
> between the two branches, and never gets confused.
> 
> Maybe I did not want to have 'j' because it was an incomplete
> solution to some problem....

Another scenario might be if 'j' was just a bad idea, and should have
never been committed in the first place.  Now if Alice builds upon it,
and at some later point Alice asks you to pull from her repository,
'j' will appear back in your repository.  So it's better to have a
changeset which simply undoes 'j' rathern than rewind, once you've
pushed out the repository.

The one exception to this is if 'j' contains something which might be
problematic from a copyright point of view, in which case you're
largely screwed if other people such as Alice has already pulled from
you and started basing changes on 'j'.

							- Ted

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Why is it bad to rewind a branch that has already been pushed out?
  2007-02-03  6:40 Junio C Hamano
@ 2007-02-03 10:40 ` Andy Parkins
  2007-02-03 19:42   ` Junio C Hamano
  2007-02-03 13:20 ` Theodore Tso
  2007-02-04 16:16 ` Robin Rosenberg
  2 siblings, 1 reply; 9+ messages in thread
From: Andy Parkins @ 2007-02-03 10:40 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

On Saturday 2007, February 03 06:40, Junio C Hamano wrote:

>     Also, don't use "git reset" on a publicly-visible branch that
>     other developers pull from, as git will be confused by history
>     that disappears in this way.
>
> I do not think this is a good explanation.  For example, if we
> do this:

I agree it's not a good explanation, I think it is good policy though.  
I love an oppourtunity to blather on and your post has given it to 
me :-)  I'm sure I'll be preaching to the converted though.

In the following I've assumed that both "h" and "a" commits are 
independent work, neither of which works on "j" (which isn't quite what 
you described).  It's not really appropriate for the tutorial, so I 
haven't really helped you.

-----------------
git's easy manipulation of branches encourages one to try to make 
history really tell the story of development.  It's more than just 
recording snapshots, there is information in the history itself - 
reasons for decisions can be recorded - separating and collecting 
commits into appropriate branches instead of one giant linear block.

As you say git is perfectly okay with the rewound branch and will do the 
Right Thing to preserve the changes.  However, it won't get the spirit 
of the changes right.

> (4) Alice pulls from me again:
>
> 	---o---o---o---j---a---a---*
>                   \             /
>                    h---h---h---h
>
> Contrary to the description, git will happily have Alice merge
> between the two branches, and never gets confused.

The problem is not that the working tree is wrong, it is that the 
history is wrong.  This sequence of development isn't best represented 
by a merge.  When we look at the history later, we'll see it as two 
branches, but that isn't true.

The graph shows that "j" was committed and then probably conflicted 
in "*" and fixed.  The problem is that you can't point to any non-merge 
commit that reverted/corrected "j" and explains why that wasn't a good 
idea - so the "story" that the history tells us is incomplete.  The 
correction was done just as a conflict resolution in "*".

Any of these would be correct:

1) "h" and "a" are parallel; "j" never happens

 ---o---o---o----a-----a----*
             \             /
              h---h---h---h

2) Alice corrects "j" with a "!j" revision - "!j" would then describe 
why "j" was wrong and what the fix was.  "h" would have to have nothing 
to do with the "j" topic in this case.

 ---o---o---o---j---!j---a---a---*
             \                  /
              h-----h-----h----h

Of course, both of these require information from the developer. (1) 
can't be done after the push has been done (because "j" is already "out 
there") and (2) requires that "h" know that Alice has fixed the problem 
and the Alice knows that the "j" problem needs fixing (and probably 
doesn't belong in Alice's branch anyway).

The only solution that keeps the history integrity, is the one that all 
the git manuals reccommend.

3) Don't rebase at all, correct the problem and record the correction.

  --o---o---o---j------a------a------*
                 \                  /
                  !j---h---h---h---h

That is - once a mistaken commit has been pushed out, it's there 
forever, accept that and don't rebase to before the last push.  
Sometimes it makes the history less pretty, but it makes it more right.  
Without "!j", no one would ever know what was wrong with "j".

In short - heed the warnings - you will get much better history if you 
don't rebase branches that have already been pushed upstream.
-----------------------

How about that as the explanation for the tutorial?  What do you mean I 
haven't simplified anything and have replaced one paragraph with a page 
worth of overly wordy ravings?  HOW DARE YOU!  :-)



Andy
-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE
andyparkins@gmail.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Why is it bad to rewind a branch that has already been pushed out?
@ 2007-02-03  6:40 Junio C Hamano
  2007-02-03 10:40 ` Andy Parkins
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Junio C Hamano @ 2007-02-03  6:40 UTC (permalink / raw)
  To: git

I was reading the tutorial and noticed that we say this:

    Also, don't use "git reset" on a publicly-visible branch that
    other developers pull from, as git will be confused by history
    that disappears in this way.

I do not think this is a good explanation.  For example, if we
do this:

(1) I build a series and push it out.

	---o---o---o---j

(2) Alice clones from me, and builds two commits on top of it.

	---o---o---o---j---a---a

(3) I rewind one and build a few, and push them out.

	---o---o---o...j
                    \
                     h---h---h---h

(4) Alice pulls from me again:

	---o---o---o---j---a---a---*
                    \             /
                     h---h---h---h

Contrary to the description, git will happily have Alice merge
between the two branches, and never gets confused.

Maybe I did not want to have 'j' because it was an incomplete
solution to some problem, and Alice may have fixed it up with
her changes, while I abandoned that approach I started with 'j',
and worked on something completely unrelated in the four 'h'
commits.  In such a case, the merge Alice would make would be
very sensible, and after she makes the merge if I pull from her,
the world will be perfect.  I started something with 'j' and
dropped the ball, Alice picked it up and perfected it while I
went on to work on something else with 'h'.  This would be a
perfect example of distributed parallel collaboration.  There is
nothing confused about it.

The case the rewinding becomes problematic is if the work done
in 'h' tries to solve the same problem as 'j' tried to solve in
a different way.  Then the merge forced on Alice would make her
pick between my previous attempt with her fixups (j+a) and my
second attempt (h).  If 'a' commits were to fix up what 'j'
started, presumably Alice already studied and knows enough about
the problem so she should be able to make an informed decision
to pick between what 'j+a' and 'h' do.

A lot worse case is if Alice's work is not at all related to
what 'j' wanted to do (she did not mean to pick up from where I
left off -- she just wanted to work on something different).
Then she would not be familiar enough with what 'j' and 'h'
tried to achieve, and I'd be forcing her to pick between the
two.  Of course if she can make the right decision, then again
that is a perfect example of distributed collaboration, but that
does not change the fact that I'd be forcing her to clean up my
mess.

So I am thinking about rewording the section like this.

Comments?

---

diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index ea34189..5fc5be5 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -458,9 +458,9 @@ $ git reset --hard HEAD^ # reset your current branch and working
 Be careful with that last command: in addition to losing any changes
 in the working directory, it will also remove all later commits from
 this branch.  If this branch is the only branch containing those
-commits, they will be lost.  (Also, don't use "git reset" on a
-publicly-visible branch that other developers pull from, as git will
-be confused by history that disappears in this way.)
+commits, they will be lost.  Also, don't use "git reset" on a
+publicly-visible branch that other developers pull from, as it will
+force needless merges on other developers to clean up the history.
 
 The git grep command can search for strings in any version of your
 project, so

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2007-02-04 20:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-03  8:42 Why is it bad to rewind a branch that has already been pushed out? linux
2007-02-03  9:04 ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2007-02-03  6:40 Junio C Hamano
2007-02-03 10:40 ` Andy Parkins
2007-02-03 19:42   ` Junio C Hamano
2007-02-04 18:01     ` Andy Parkins
2007-02-03 13:20 ` Theodore Tso
2007-02-04 16:16 ` Robin Rosenberg
2007-02-04 20:08   ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.