Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly apply a patch with moved/renamed files using Git

Tags:

git

patch

I'm trying to properly create and apply patches using Git:

  1. I created a new git project, with two files: first.txt and second.txt
  2. I create a branch
  3. In this new branch, I modify the content of both files and commit
  4. I move the file second.txt to folder\second_moved.txt and commit

Now I create a patch with git format-patch master --stdout > changes.patch.

Here is the content of changes.patch:

From cb2a85ff9a0bc36d4f04fbe72068ae9ec3a9bcb0 Mon Sep 17 00:00:00 2001
From: 
Date: Mon, 29 Sep 2014 20:46:18 -0400
Subject: [PATCH 1/2] changes

---
 fist.txt   | 2 +-
 second.txt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fist.txt b/fist.txt
index d4b4f36..b5d9ba4 100644
--- a/fist.txt
+++ b/fist.txt
@@ -1 +1 @@
-first file
\ No newline at end of file
+first file foobar
\ No newline at end of file
diff --git a/second.txt b/second.txt
index 0f8bbfe..54e687e 100644
--- a/second.txt
+++ b/second.txt
@@ -1 +1 @@
-second file
\ No newline at end of file
+second file barfoo
\ No newline at end of file
-- 
1.8.4.msysgit.0


From 09c868828cf30fba36ba04cbd476dfcb0f68f79c Mon Sep 17 00:00:00 2001
From: 
Date: Mon, 29 Sep 2014 20:47:15 -0400
Subject: [PATCH 2/2] moved

---
 folder/second_moved.txt | 1 +
 second.txt              | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 folder/second_moved.txt
 delete mode 100644 second.txt

diff --git a/folder/second_moved.txt b/folder/second_moved.txt
new file mode 100644
index 0000000..54e687e
--- /dev/null
+++ b/folder/second_moved.txt
@@ -0,0 +1 @@
+second file barfoo
\ No newline at end of file
diff --git a/second.txt b/second.txt
deleted file mode 100644
index 54e687e..0000000
--- a/second.txt
+++ /dev/null
@@ -1 +0,0 @@
-second file barfoo
\ No newline at end of file
-- 
1.8.4.msysgit.0

Now, I move back to my master branch and apply the patch with git apply changes.patch. There is no error.

Here is the result of git status:

# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   fist.txt
#       modified:   second.txt
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       changes.patch
#       folder/
no changes added to commit (use "git add" and/or "git commit -a")

As you can see, I still have the file second.txt. I'm not expecting this, but I expect it should have been removed as it's been moved in folder. In folder, I actually get the file second_moved.txt. Both files' content has been correctly modified by git apply.

As I'm expecting to use git to generate and apply patches to branches of code that will be largely refactored, I cannot afford to manually track and delete all files that have been changed, then moved or renamed. How can I avoid this?

like image 548
slaadvak Avatar asked Sep 30 '14 01:09

slaadvak


People also ask

What happens if you rename a file that is tracked by Git?

Git keeps track of changes to files in the working directory of a repository by their name. When you move or rename a file, Git doesn't see that a file was moved; it sees that there's a file with a new filename, and the file with the old filename was deleted (even if the contents remain the same).

How do patches work in Git?

GIT patch or GIT diff is used to share the changes made by you to others without pushing it to main branch of the repository. This way other people can check your changes from the GIT patch file you made and suggest the necessary corrections.

How do I create a patch in git?

To create a Git patch file, you have to use the “git format-patch” command, specify the branch and the target directory where you want your patches to be stored.


1 Answers

try using

git am changes.patch

instead of git apply

From the man page "Use git-am(1) to create commits from patches generated by git-format-patch(1)"

Tested on Git 2.1.1. I see the same apply behavior you get, but am works properly.

like image 107
Andrew C Avatar answered Sep 28 '22 07:09

Andrew C