Quuxplusone Quuxplusone - 4 months ago 20
Git Question

How to add additional parents to old git commits?

I have a project containing two branches: master and gh-pages. They are essentially two different projects, where the gh-pages project depends on the master project (and not vice versa). Think of it as "master contains the source code, gh-pages contains the binary built from those source files". Periodically, I take the changes that have accumulated in master and make a new commit to the gh-pages branch with the commit message "Bring into line with master commit xxxxxxxx."

how the network graph currently looks

After a while of doing this, I realized that it would be nice if the gh-pages commit "Bring into line with master commit xxxxxxxx" actually had xxxxxxxx as its parent in the git repository. Like this (bad MSPaint art):

how it would ideally look

Is there a way to make the repository look like the second image above? I know how to make new commits follow this pattern: I can do "git merge -s ours master" (which sets the parents of an otherwise empty commit) followed by "git commit --amend adv550.z8" (where adv550.z8 is the binary file that's actually changing). But does git make it easy to go back in time and add new parents to old commits?

I am perfectly willing to "git push -f" and blow away the current history of my Github repository, once I get my local repo looking right. The question is, can I get my local repo looking right?




EDITED YEARS LATER TO ADD: I eventually abandoned my attempts to make the git history of
gh-pages
look like that; I decided that it was too much work for zero gain. My new practice is to aggressively squash commits to
gh-pages
, because saving those commit messages really doesn't matter in my case. (It's just a long line of "Bring into line with master commit..."s, none of which are historically interesting.) However, if I needed to do this again, I'd listen to the answers that said

git merge $intended_parent_1 $intended_parent_2
git checkout $original_commit -- .
git commit --amend -a -C $original_commit

Answer

You can't go back in time and change existing commits. Even when you do something like git commit --amend, you're not actually changing the commit; you're creating a new one at the same place in the tree with all the content from the original (plus your changes). You'll notice that the commit hash changes after the --amend, and the original is still present in your repo--you can get back to it with git reflog.

On the other hand, you can go back in time and create an alternate universe. Essentially, you would go back to your gh-pages branch point and recreate the whole thing (with e.g. git cherry-pick or something) as a parallel branch. The hashes would change, because the commits are different objects.

(I'm curious why you have your repo set up as separate branches, instead of separate directories in the same branch. It seems like the code -> build process would get tedious.)

Comments