Revising git repo history to become linear
Asked Answered
O

1

7

We need to generate a TFS repository from a Git source code base, we would like to preserve the original commit history, so I tried to use Tf-Git "git tf checkin --deep" command that is supposed to create a TFS changeset for each Git commit.

Unfortunately this step fails because a lot of commits in the Git repo have two parents due to merges, and TFS requires commit history to be linear to be able to import it. So I am getting the following error:

git-tf: cannot check in - commit 2b15822 has multiple parents, please rebase to form a linear history or use --shallow or --autosquash

This is understandable. But what can be done about it if the existing Git repo has a long chain of such commits? I know it's possible to spend a day or two revising commit history manually, but that's not what we want to spend our days on. Do I understand correctly that there is no automated way of fixing commit history to become linear, so unless we want to spend many hours on manual work, we should just import the whole history as a single changeset?

Ossa answered 5/2, 2013 at 9:38 Comment(1)
Does this answer your question? Linearize git history, preserving all commitsHolography
P
12

A rebase should actually solve this for you.

git rebase -i <hash of commit before first branch has been created>

In the window that pops up when you execute that command, don't change anything. Simply save and close.

An illustration:

A <- B <- E <-----F <- G      master
     ^            ^
      \          /
       - C <- D -             branch

Commits C and D were on a branch and have been merged into master with the merge commit F.

Now, executing git rebase -i B will yield the following result, when executed from master:

A <- B <- C <- D <- E <- G    master

Please note that the merge commit F disappeared, because it would be empty.

Peculiarity answered 5/2, 2013 at 9:47 Comment(7)
Let me check if I understand you, Daniel. I ran "git rebase -i <hash of the commit>". I am getting a windows where I can save the rebase. But this does only rebase a few commits, not the whole history. Should I go through the whole tree and repeat it for all branched nodes?Ossa
I don't know how complex your history is, but if you choose the commit before the first branch, you should get a linear history. BTW: The window is not for saving the rebase - in that window you can actually change the commits by changing their order etc. But that's not what we want to do here.Peculiarity
@VagifAbilov: Please note: I highlighted "before the first branch" in my comment. I changed my answer accordingly. The last commit before the first branch has been created is the right one to use.Peculiarity
Thank you Daniel, it makes sense. I have started rebasing from the commit before the first branch, it triggered rebase of ca. 1700 items. Looks like the workflow is correct, unfortunately I am getting now an error "error: addinfo_cache failed for path '<some path>'", but this seems to be another problem.Ossa
@VagifAbilov: yes, it will be a huge rebase. It is basically rewriting your complete history. About the error: Make sure you have no programs open that lock any files or paths inside your repository.Peculiarity
Yes, it's taking time but going well now. addinfo_cache was easily resolved like it was a merge conflict, the message was misleading. Thanks again for your help.Ossa
is it possible to preserve merge commit, but make it simple commit?Pokpoke

© 2022 - 2024 — McMap. All rights reserved.