I want to reverse a git filter-branch and want to know the best way to do this.
Originally I had a repo like this :
A
p
q
r
I then made q its own repo so that I had this:
A
p
r
Q
Now, many commits later, I want to reverse that operation to return q to its original parent A. How can I get Q back to A.q and keep all history?
Best Answer
A few approaches come to mind. I recommend trying these in a clone of the repository to make changing your mind & trying something else trivial. (Though even if you accidentally did it in your only copy, recovery using the reflog and
git reset
ought to be possible).git subtree
, without--squash
. This will probably do something close enough to what you want. The command would be (inside A) something likegit subtree add -P q git://user@host/path/Q.git master
. A will still be fast-forwardable.If you want to customize it more, you can use subtree merge (which I'm pretty sure git-subtree uses internally). A will still be fast-forwardable.
git-filter-branch can do basically anything, no reason it can't merge repositories. You could (for example) pull Q into a branch of A, then filter-branch it to move it all under the q subdirectory, then merge it to master (with
--allow-unrelated-histories
). That'll change all the commit IDs for Q, but not A. Or you could use commit, etc. filters to put the commits together into a history however you'd like (which of course will change a lot of commit IDs, so unless very careful, A will not be fast-forwardable).PS: While questions about programs running on Unix/Linux systems are OK here, there is a lot more expertise about git (and other development tools) on Stack Overflow. It's up to you, but I'd personally ask git questions over there, as I think you'll get quicker and quite possibly better answers on SO.