Reputation: 5072
I was working on a branch taken from master branch for sometime. Now I need to merge my changes. The changes are in specific folder e.g. admin which is a subdirectory in my project.
When I took the latest from master branch, this directory is moved to another location e.g. master/admin. So, now when I try to merge, it shows me all of the admin related files as new file.
I would like to avoid any manual effort to merge and would like a way so that I can let git know that this is not new folder but is the existing folder which has been moved.
Upvotes: 4
Views: 6477
Reputation: 1329292
Git 2.18 (Q2 2018) should facilitate such a merge.
Rename detection logic in "diff
" family that is used in "merge
" has
learned to guess that:
x/a
, x/b
and x/c
have moved to z/a
,
z/b
and z/c
,x/d
added in the meantime would also
want to move to z/d
x
' moved to 'z
'.See commit 1de70db, commit 05cf21e, commit 277292d, commit a35edc8, commit c04ba51, commit 2f682e2, commit bd42380, commit fd53b7f, commit 6e7e027, commit bc71c4e, commit 18797a3, commit 64b1abe, commit 79c4759, commit 9c0743f, commit 5b047ac, commit f6f7755, commit e95ab70, commit 96e7ffb, commit 7fe40b8, commit ffc16c4 (19 Apr 2018) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit c67de74, 23 May 2018)
You can see the new tests for merge with moved folders in t/t6043-merge-rename-directories.sh
.
It details scenarios like:
###########################################################################
# SECTION 1: Basic cases we should be able to handle
###########################################################################
# Testcase 1a, Basic directory rename.
# Commit O: z/{b,c}
# Commit A: y/{b,c}
# Commit B: z/{b,c,d,e/f}
# Expected: y/{b,c,d,e/f}
The expected result would be when merging branch B
into A
.
That includes more complex use-cases:
# Testcase 1f, Split a directory into two other directories
#
# Commit O: z/{b,c,d,e,f}
# Commit A: z/{b,c,d,e,f,g}
# Commit B: y/{b,c}, x/{d,e,f}
# Expected: y/{b,c}, x/{d,e,f,g}
The bottom line is:
So, now when I try to merge, it shows me all of the admin related files as new file
That should no longer be the case with Git 2.18.
With Git 2.25 (Q1 2020), when all files from some subdirectory were renamed to the root directory, the directory rename heuristics would fail to detect that as a rename/merge of the subdirectory to the root directory, which has been corrected.
See commit da1e295, commit 49b8133, commit d3eebaa (22 Oct 2019) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit d980035, 10 Nov 2019)
merge-recursive
: fix merging a subdirectory into the root directorySigned-off-by: Elijah Newren
We allow renaming all entries in e.g. a directory named
z/
into a directory namedy/
to be detected as az/ -> y/
rename, so that if the other side of history adds any files to the directoryz/
in the mean time, we can provide the hint that they should be moved toy/
.There is no reason to not allow '
y/
' to be the root directory, but the code did not handle that case correctly.
With Git 2.25 (Q1 2020), that merge fix includes some code cleanup.
See commit 675ef6b, commit 01ed17d, commit f670adb (18 Dec 2019), and commit 8c02fe6, commit cb05d6a (11 Dec 2019) by René Scharfe (``).
(Merged by Junio C Hamano -- gitster
-- in commit 8be0a42, 25 Dec 2019)
t3501
: don't create unused fileSigned-off-by: René Scharfe
The file "
out
" became unused with fd53b7ffd1 ("merge-recursive
: improveadd_cacheinfo
error handling", 2018-04-19, Git v2.18.0-rc0 -- merge listed in batch #6); get rid of it.
Upvotes: 3
Reputation: 142632
So, now when I try to merge, it shows me all of the admin related files as new file.
Restore the old branch
and move the file with git mv
and not a simple mv
command.
Why do i have to use git mv and not just mv?
Git does not track file names. it store the content inside a .pack
file and the file names (metadata) inside a .idx
file and its not part of the content itself.
To get to know it much better read this out how does git store file names
https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#Tree-Objects
Git cannot track moved files unless you moved them with the git mv
.
If you simply move or rename them git will track them as new files and will delete the old one.
How to track changes of the moved files?
# you have to use the --follow flag
git log --follow ./path/to/file
Upvotes: 6
Reputation: 522741
The answer by @CodeWizard
looks good, but if that doesn't work then would there be anything wrong with simply adding the entire new folder?
Use this:
$ cd master
$ git add admin
Upvotes: 0