Re: [PATCH] push: point to 'git pull' and 'git push --force' in case of non-fast forward

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

 



Matthieu Moy <Matthieu.Moy@xxxxxxx> writes:

> Junio C Hamano <gitster@xxxxxxxxx> writes:
>
>> +Alternatively, you can rebase your change between X and B on top of A,
>> +with "git pull --rebase", and push the result back.  The rebase will
>> +create a new commit D that builds the change between X and B on top of
>> +A.
>> +
>> +----------------
>> +
>> +      B   D
>> +     /   /
>> + ---X---A
>> +
>> +----------------
>> +
>> +Again, updating A with this commit will fast-forward and your push will be
>> +accepted.
>
> Maybe add something about --force ? I don't like my wording very much,
> but a first try is this:
>
> Lastly, you can decide that the B shouldn't have existed, and delete
> it. This is to do with a lot of care, not only because it will discard
> the changes introduced in B, but also because if B has been pulled by
> someone else, he will have a view of history inconsistant with the
> original repository. This is done with the --force option.

To be consistent with the flow, I think you are discarding A in the
example, not B.  A is what somebody else pushed out before your failed
attempt of pushing B, and --force will discard A, replacing its history
with yours.

Of course, you also could decide that somebody else's change A is vastly
superior than your crappy B, and you may decide to do "git reset --hard A"
to get rid of your history locally; but you wouldn't be using "git push"
after that.  It is an equally valid outcome in the example situation and
until you fetch to see what A is, you cannot decide.

So, probably the order to teach would be:

 - You can pull to merge, or pull --rebase to rebase; either way, you are
   trying to preserve both histories.  [I've written on this in the
   previous message]

 - But you may realize that the commit by the other (i.e. A) was an
   incorrect solution to the same problem you solved with your B.  You
   _could_ force the push to replace it with B in such a case.  You need
   to tell the person who pushed A (and everybody else who might have
   fetched A and built on top) to discard their history (and rebuild their
   work that was done on top of A on top of B). [This is yours with A <=> B]

 - Alternatively you may realize that the commit by the other (i.e. A) was
   much better solution to the same problem you tried to solve with your
   B.  In such a case, you can simply discard B in your history with "git
   reset --hard A" after fetching.  You wouldn't be pushing anything back
   in this case.

I actually do not think it is appropriate to teach --force in an example
that involves more than one person (iow, in the context of the example in
my patch).  A lot better alternative in such a case is to "git merge -s
ours A" and push the result out, which keeps the fast-forwardness for the
person who did A, and others who pulled and built on top of A already.

So scratch your "lastly", replace it (and the second point in my list
above) with:

 - You may realize that the commit by the other (i.e. A) was an incorrect
   solution to the same problem you solved with your B.  In such a case,
   do _not_ use --force to remove A from the public history.  Instead,
   resolve the merge (in the previous instruction) favoring your solution,
   e.g. "git pull -s ours", and push the result out.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]