Skip to main content
Topic: Git pain - ****istance requested from Git experts (Read 8211 times) previous topic - next topic

Git pain - ****istance requested from Git experts

Forgive me if I have posted this in the wrong section; I was not quite sure which would be most appropriate for a topic of this sort. I am having terrible trouble trying to make Git merge two branches. I maintain two development branches for Experimental: 8.x for bugfixes, and -devel for more major changes. What I want to do is merge the bugfixes in 8.x into -devel. The problem is that, at one point, I accidentally merged -devel into 8.x, then reverted it. Now, when I try to merge 8.x into -devel, it reverts all the changes made in -devel since 8.x was forked from it because it also merges the revert. Merging then reverting the revert causes seemingly random results that bear no relationship to the desired merge. This is causing me very serious difficulty: any ****istance would be very much appreciated.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #1
The problem is that, at one point, I accidentally merged -devel into 8.x, then reverted it.

By revert, do you mean you have created a commit to revert it? And have you pushed your problematic branch up to Github?

Re: Git pain - ****istance requested from Git experts

Reply #2
By revert, do you mean you have created a commit to revert it? And have you pushed your problematic branch up to Github?


Thank you for your swift reply. I used the "git revert" command, which does automatically commit. The only revert commit pushed to Github is the earlier revert in the 8.x branch. My further test reverts on the -devel branch I have not pushed.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #3
If you have not pushed the problematic merge and the ensuing revert commit to Github, you may try to reset your 8.x branch to the commit immediately prior to the problematic merge. Open the repository browser (Gitk), choose the appropriate commit to revert to on the 8.x branch, right-click on that commit and choose "Revert 8.x branch to here", then choose the reset type "Hard" which resets both the working tree and index. After that, the merge and revert commits should be gone.

Re: Git pain - ****istance requested from Git experts

Reply #4
Knightly,

I am a little confused. The problematic merge in the 8.x branch has been pushed. It is the later merge from the 8.x branch into -devel that has not been pushed. Further, if I were simply to reset the branch to the point of the incorrect merge from -devel into 8.x, all of the useful bug fixes that I have since put into 8.x would be lost - how would one go about saving those?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #5
If you have made the changes public (i.e. they are already published at Github), it is not desirable to reset anymore, or you will mess up other developers' local repository.

Edit :

If you are satisfied that 8.x takes in changes involved in your previous problematic merge, you may, on your 8.x branch, revert your problematic revert (which reverts your problematic merge) first before checking out the devel branch and merging again from the 8.x branch.


Re: Git pain - ****istance requested from Git experts

Reply #6
Knightly,

thank you for your reply; what do you mean by "8.x takes in changes" here?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #7
Code: [Select]
----W----X----M----R----Y----Z----> 8.x
----A----B----^----C----D----E----> devel

M is the problematic merge, and R is the revert that reverts the problematic merge. What I mean is, if it is acceptable to you that 8.x merges changes from devel prior to the problematic merge (i.e. A and B, etc. which were originally merged in the problematic merge), then you can try reverting R on 8.x branch first, before checking out devel and merge again from 8.x.

Re: Git pain - ****istance requested from Git experts

Reply #8
I'm still a little confused, I'm afraid, for two reasons. Firstly, I don't know what you mean here by "8.x merge changes from devel prior to the problematic merge" - the 8.x merge changes what from -devel? Or do you mean deviates from -devel?

Secondly, the diagram does not describe the position in which I find myself. It is more like this:

Code: [Select]
----W----M----X----R----Y----Z--->8.x
----A----^----B-----C----D----E--->devel

I need to get X, Y and Z into the -devel branch, and I had made changes to 8.x before noticing the inappropriate merge and then reverting it.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #9
Answers to your questions :

1) I am talking about A (in your diagram), and any commits that comes before A, which got merged into 8.x in your problematic merge

2) My diagram is not intended to be an exact replicate of your existing network graph at Github; it merely highlights the main commits and the relationships among them.

3) I suggest you to revert R on 8.x, if you don't mind A (and some other commits in devel that comes before A) to be present in 8.x. In that way, when you merge 8.x into devel, the past commits A (and some other commits in devel that comes before A) will still be preserved.



Re: Git pain - ****istance requested from Git experts

Reply #10
Ahh, the problem is that I do mind the -devel commits being on 8.x: not having -devel commits on 8.x is the whole point of having 8.x.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #11
Since you have tried "merging first, then reverting R" in the devel branch and failed, obviously GIT does not allow you to revert a "revert on merge" on a branch different from the original branch where the original merge and revert was committed.

If you insist not to allow those commits (A, etc.) from devel in 8.x, you can create a new branch off the commit W, then reconstruct the branch by manually cherry-pick commits from 8.x (of course, exclude M and R), and when done, remove the 8.x branch altogether. But since the master branch is now in sync with 8.x, this is not even easily doable without discarding the master branch.

That's all I can think of.

Edit :

Another solution. You may keep cherry-picking from 8.x into devel until those commits (A, etc.) are ready for inclusion in 8.x. At that time, you revert R on 8.x, and then merge the other relevant changes from devel. Of course, that would mean a lot more manual work before those commits (A, etc.) are ready for inclusion.

Anyway, since R (which reverts changes from A, etc.) has been incorporated in both 8.x and master, eventually you will need to revert R (unless you choose to discard both 8.x and master) -- even if you merge devel into 8.x later on, you will not get the reverted changes (A, etc.) back.

Re: Git pain - ****istance requested from Git experts

Reply #12
The way I would solve this is to change the workflow so that you're always committing fixes to devel, and then cherry picking applicable changes to 8.x (in stead of committing to 8.x and then merging into devel).

It's not a great solution, but I think the workflow of making changes in devel then cherry-picking them into 8.x is cleaner and easier to follow in any case.

Otherwise, as Knightly says you'll probably have to make a new branch without the merge, or somehow manually sort out the revert-reversion in devel :(.

Re: Git pain - ****istance requested from Git experts

Reply #13
Thank you both for your help. It is very frustrating that Git is not designed better so as to provide an easy way out to what must be a common error. Reverting does not seem to be properly clean.

The only thing that I can think to do is to cherry pick all of the changes that I want from 8.x into -devel (there are far fewer of those than the other way around). 8.x will eventually either become obsolete or be over-written by -devel as the changes on -devel become mature enough to include in 8.x.

Yobbobandana's suggested workflow is, alas, impractical, since cherry-picking cannot be done in the GUI, and requires manually specifying each and every commit, making a specific patch file for each and every commit, then applying that patch file. This is too time consuming to be a viable answer.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Re: Git pain - ****istance requested from Git experts

Reply #14
would this be a possible workaround:
revert the first revert in 8.x (1)
merge 8.x into devel
revert the new revert (1) in 8.x again


can't you cherrypick in github?  'fork queue'

Re: Git pain - ****istance requested from Git experts

Reply #15
It is very frustrating that Git is not designed better so as to provide an easy way out to what must be a common error.

There is already an easy way out if you realise earlier on that the merge is faulty, before committing further and pushing to Github -- simply by resetting. But you didn't check, at the time of merge, and you didn't check, at the time of push. You let the situation develop into a state which is not easily revertible anymore -- and you don't blame yourself for your own negligence, but blame GIT? I don't believe that there can be any advanced hacking tool that the GIT team can build to solve your problem.


Reverting does not seem to be properly clean.

Reverting a merge does NOT undo/remove a merge; it merely revert the changes ****ociated with the merge. The merge commit and hence the merge point between the 2 branches are preserved. Your situation is like this : you merge A, etc. into 8.x, and the "revert of merge" reverts the changes ****ociated with A, etc. Thus when you merge 8.x back into devel, changes A, etc. in devel are removed by that "revert of merge" commit. There is nothing wrong with GIT's design of revert. If you ****ume that revert undoes a merge entirely, you are wrong.


Yobbobandana's suggested workflow is, alas, impractical, since cherry-picking cannot be done in the GUI, and requires manually specifying each and every commit, making a specific patch file for each and every commit, then applying that patch file. This is too time consuming to be a viable answer.

Who said cherry-picking cannot be done via GUI? You have been working with GIT for over one year already, but have you seriously explored its functionality at all? In Gitk, the repository browser, if you right-click on a commit which is not on the current branch, there is an option for you to cherry-pick it and merge it into the currently checked-out branch. And who told you that you need to create patches and repatch -- even for command-line cherry-pick tool, you don't need to work with patches.

Re: Git pain - ****istance requested from Git experts

Reply #16
My only criticism of git has always been that it makes it so incredibly easy to shoot yourself in the face ;).

I had a try with a copy of the devel and 8.x branches, and concluded the easiest thing by far to do to obtain the previous setup, is to replace the 8.x branch with a new branch which doesn't have the offending merge.


would this be a possible workaround:
revert the first revert in 8.x (1)
merge 8.x into devel
revert the new revert (1) in 8.x again
Sadly this would only work until the next time 8.x was merged into devel, at which point it would again be a problem :).


For some related info on the complications of reverting merges, here's the semi-official documentation:
http://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.txt
It doesn't cover this specific situation, however.

Re: Git pain - ****istance requested from Git experts

Reply #17
I had a try with a copy of the devel and 8.x branches, and concluded the easiest thing by far to do to obtain the previous setup, is to replace the 8.x branch with a new branch which doesn't have the offending merge.

Yes, creating a new branch off W and cherry-picking commits (other than M and R) from 8.x should be the better solution, as that only needs to be done once and saves the trouble later. After second thought, the master branch can be left as it is at the moment, as there is no need to merge from master into 8.x or devel; but one has to remember to revert R on the master branch when those commits (A, etc.) are ready for inclusion into master.

Re: Git pain - ****istance requested from Git experts

Reply #18
Forgive me if I have posted this in the wrong section; I was not quite sure which would be most appropriate for a topic of this sort. I am having terrible trouble trying to make Git merge two branches. I maintain two development branches for Experimental: 8.x for bugfixes, and -devel for more major changes. What I want to do is merge the bugfixes in 8.x into -devel. The problem is that, at one point, I accidentally merged -devel into 8.x, then reverted it. Now, when I try to merge 8.x into -devel, it reverts all the changes made in -devel since 8.x was forked from it because it also merges the revert. Merging then reverting the revert causes seemingly random results that bear no relationship to the desired merge. This is causing me very serious difficulty: any ****istance would be very much appreciated.

OK.  In future the thing to do is to repoint the 8.x branch tag at the point before the erroneous merge, instead of reverting the merge, using a "reset".  (If you've already pushed the erroneous merge to github, this breaks other people updating from 8.x who updated while the erroneous version was out there, but that shouldn't be a major issue if you get to it quickly -- I've actually done that four or five times and nobody noticed.) 

But it's too late for that once you have additional patches on the 8.x branch.

At *present* the thing to do is to branch 8.x-new from the point before the erroneous merge (ad76397157f...), and then cherry-pick ('git cherry-pick' or the equivalent in the GUI) the useful commits from after the erroneous merge, and then to merge the 8.x branch into devel, as yobbobandana and Knightly suggest.

I could do this in less than a minute at the command line.  It's perfectly straightfoward in the GUI too.

Where's the erroneous merge and where's the revert?... Oh, I see  (from looking at http://github.com/jamespetts/simutrans-experimental/network ).  There's only six commits after the revert, and two between the erroneous merge and the revert!  This should not take very long!

Re: Git pain - ****istance requested from Git experts

Reply #19
Nathaneal,

that is very kind. I had in any event manually applied the additional 8.x commits to -devel, and pushed the results; does that change anything?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

 

Re: Git pain - ****istance requested from Git experts

Reply #20
Nathaneal,

that is very kind. I had in any event manually applied the additional 8.x commits to -devel, and pushed the results; does that change anything?

It changes things a little tiny bit.  You *still* want to do this:
Quote
At *present* the thing to do is to branch 8.x-new from the point before the erroneous merge (ad76397157f...), and then cherry-pick ('git cherry-pick' or the equivalent in the GUI) the useful commits from after the erroneous merge

Your 8.x branch is 'damaged' -- in that it's not safe to merge it to devel.  If you want to keep the 8.x branch around for a long time you'll need to make a new 8.x branch.

If you're just ready to drop the 8.x branch and make a new release branch (9.x?) direct from -devel, then you don't need to do much of anything.