Is it possible to move/rename files in Git and maintain their history?

前端 未结 14 2349
梦如初夏
梦如初夏 2020-11-22 04:42

I would like to rename/move a project subtree in Git moving it from

/project/xyz

to

/components/xyz

If I

14条回答
  •  一个人的身影
    2020-11-22 05:44

    It is possible to rename a file and keep the history intact, although it causes the file to be renamed throughout the entire history of the repository. This is probably only for the obsessive git-log-lovers, and has some serious implications, including these:

    • You could be rewriting a shared history, which is the most important DON'T while using Git. If someone else has cloned the repository, you'll break it doing this. They will have to re-clone to avoid headaches. This might be OK if the rename is important enough, but you'll need to consider this carefully -- you might end up upsetting an entire opensource community!
    • If you've referenced the file using it's old name earlier in the repository history, you're effectively breaking earlier versions. To remedy this, you'll have to do a bit more hoop jumping. It's not impossible, just tedious and possibly not worth it.

    Now, since you're still with me, you're a probably solo developer renaming a completely isolated file. Let's move a file using filter-tree!

    Assume you're going to move a file old into a folder dir and give it the name new

    This could be done with git mv old dir/new && git add -u dir/new, but that breaks history.

    Instead:

    git filter-branch --tree-filter 'if [ -f old ]; then mkdir dir && mv old dir/new; fi' HEAD
    

    will redo every commit in the branch, executing the command in the ticks for each iteration. Plenty of stuff can go wrong when you do this. I normally test to see if the file is present (otherwise it's not there yet to move) and then perform the necessary steps to shoehorn the tree to my liking. Here you might sed through files to alter references to the file and so on. Knock yourself out! :)

    When completed, the file is moved and the log is intact. You feel like a ninja pirate.

    Also; The mkdir dir is only necessary if you move the file to a new folder, of course. The if will avoid the creation of this folder earlier in history than your file exists.

提交回复
热议问题