Say you've committed a file of type foo in your favorite vcs:

$ vcs add data.foo
$ vcs commit -m "My data"

After publishing you realize there's a better data format bar. To convert you can use one of these solutions:

$ vcs mv data.foo data.bar
$ vcs commit -m "Preparing to use format bar"
$ foo2bar --output data.bar data.bar
$ vcs commit -m "Actual foo to bar conversion"


$ foo2bar --output data.foo data.foo
$ vcs commit -m "Converted data to format bar"
$ vcs mv data.foo data.bar
$ vcs commit -m "Renamed to fit data type"


$ foo2bar --output data.bar data.foo
$ vcs rm data.foo
$ vcs add data.bar
$ vcs commit -m "Converted data to format bar"

In the first two cases the conversion is not an atomic operation and the file extension is "lying" in the first commit. In the last case the conversion will not be detected as a move operation, so as far as I can tell it'll be difficult to trace the file history across the commit. Although I'd instinctively prefer the last solution, I can't help thinking that tracing history should be given very high priority in version control. What is the best thing to do here?

  • Your question seems specific to Git, because the commands match and you say "the conversion will not be detected". Some other source control systems specifically track renames so this wouldn't be an issue at all. You might get better answers if you specifically refer to Git in your question. Jun 10, 2012 at 22:26
  • Either that or he's specifically asking about Subversion which does different things if you mv versus rm/add.
    – Ken Bloom
    Jun 10, 2012 at 22:28
  • Looks like Subversion tracks moves explicitly, and Git implicitly.
    – l0b0
    Jun 10, 2012 at 23:39

2 Answers 2


I would prefer the last solution.

However, regardless of what solution you choose, you should make sure that you record the exact version and arguments of the converter tool in the commit message. The reason for this is that in all three solutions the diff(s) simply won't make sense. You simply cannot sensibly review the commits.

But what you can do, is checkout the old commit, run the tool yourself and verify that its output matches the new commit. That way, you don't have to trust the huge unreadable diff, you only have to trust the tool.


Well, in git (and others like it as well), it doesn't matter whether you specifically move the file or not. The information about the move operation isn't stored in the repository. Git calculates it based on file similarity when you're working with the history. If the converted file is very different from the original (which I'd guess is likely), it won't know the two files are related, regardless of what order you commit things. If the converted file is similar, it will know the two files are related, regardless of whether you use git mv or git add on one file and git rm on the other. (git mv is simply shorthand for those two commands).

But you're talking about subversion specifically, where the svn mv command is recorded in the repository, and I can't answer what the best practice should be, because I dont use subversion anymore, though I'll say that your line of reasoning definitely makes sense.

  • It looks like Git can follow the history across renames if the content doesn't change "too much" in the same commit, and this is precisely the issue: Even a binary conversion should be a single commit, but should be easily traversed in the log.
    – l0b0
    Jun 10, 2012 at 23:42
  • 1
    @l0b0: I see now... your two-commit solutions are intended to change the content of the file in one commit, and then change the name in another commit. I guess those work, but I remember reading that Linus just objects to the whole idea of tracking the history of individual files. Following his line of reasoning, you'd use a single-commit solution, and generally restrict yourself to looking at repository history as a whole, or the history of subtrees that don't move around. You don't have to subscribe to his line of thinking, but if you don't, individual file history is a little hacky.
    – Ken Bloom
    Jun 10, 2012 at 23:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.