1

We have an main application(say main) which creates several sub applications.Currently we have decided to move one sub application (say man_ex)out of the main app folder.We are able to run the man_ex application by creating a new folder in the same branch (say newmanapp) and moving the required files into it.

However some of the required files are a part of the main application.hence we cannot move them to the man_ex folder.We can only copy them.The problem with copy is that we are not able to see the history of these files in VSTS.Although git log --follow lets me see the log in command prompt but we need to see the history in VSTS as it is.

Note: I am able to see the history by doing MV command but then the files would be deleted in the source folder.I need a copy with history kind of thing.

I have tried few solutions like below but doesn't work for me. GIT copy file preserving history

vinodsaluja
  • 573
  • 6
  • 15
  • 1
    Git can't always track files across rename or move operations. If you want to maintain a pristine history always, then your best bet is to not move/rename files. – Tim Biegeleisen Apr 22 '19 at 06:24
  • 1
    Short answer No, there is not Git copy command, for details refer this: [link](https://stackoverflow.com/questions/47401843/git-copy-file-as-opposed-to-git-mv) – vinodsaluja Apr 22 '19 at 06:54
  • you could duplicate the entire history on a orphan branch and then merge them together. – Lux Apr 22 '19 at 15:05
  • @Lux already tried that but after the merge the main app folder which has most of the applications is missing.Looks like that got overwritten by man_ex folder. – user3492389 Apr 23 '19 at 11:53
  • Then you did it wrong. It's a bit a delecate operation with filter-branch. – Lux Apr 23 '19 at 15:29
  • do you mean we need to do a different kind of merge ?.. I just ran git merge in the checkedout branch – user3492389 Apr 26 '19 at 05:08
  • Is this a duplicate of https://stackoverflow.com/questions/47401843/git-copy-file-as-opposed-to-git-mv ? – David Cary Jan 12 '22 at 05:00

1 Answers1

0

It can be done, but you need to use a separate branch to first move the files to the new location, then go back to the original branch and merge the branch where you moved the files and force git to keep the original files.... this way you get to have a "duplicate" and git will be able to see the history of the copied files (in the merge commit) without issues by going through the side branch as that is, to git, where the files are coming from.

git checkout -b rename-branch
git mv a.txt b.txt
git commit -m "Renaming file"
# if you did a git blame of b.txt, it would _follow_ a.txt history, right?
git checkout main
git merge --no-ff --no-commit rename-branch
git checkout HEAD -- a.txt # get the file back
git commit -m "Not really renaming file"

With a straight copy, you get this:

$ git log --graph --oneline --name-status
* 70f03aa (HEAD -> master) COpying file straight
| A     new_file.txt
* efc04f3 (first) First commit for file
  A     hello_world.txt
$ git blame -s new_file.txt
70f03aab 1) I am here
70f03aab 2) 
70f03aab 3) Yes I am
$ git blame -s hello_world.txt
^efc04f3 1) I am here
^efc04f3 2) 
^efc04f3 3) Yes I am

Using the rename on the side and getting the file back when merging you get:

$ git log --oneline --graph master2 --name-status
*   30b76ab (HEAD, master2) Not really renaming
|\  
| * 652921f Renaming file
|/  
|   R100        hello_world.txt new_file.txt
* efc04f3 (first) First commit for file
  A     hello_world.txt
$ git blame -s new_file.txt
^efc04f3 hello_world.txt 1) I am here
^efc04f3 hello_world.txt 2) 
^efc04f3 hello_world.txt 3) Yes I am
$ git blame -s hello_world.txt
^efc04f3 1) I am here
^efc04f3 2) 
^efc04f3 3) Yes I am

Rationale is that if you want to see history of the original file git will do it without issues.... if you want to do it on the copy, then git will follow the separate branch where the rename is and then it will be able to jump to the original file following the copy, just because it's done on that branch.

eftshift0
  • 26,375
  • 3
  • 36
  • 60