threads / patch / 10034

patchAdd --no-rename to git-apply

Subject: [PATCH] Add --no-rename to git-apply

## tl;dr

6 messages between Sep 26, 2007 and Sep 27, 2007. Diffs are folded; open one to read it.

replies: 5people: 3as markdown or json

Robin Rosenberg· Sep 26, 2007, 21:26 UTC · lore

With this option git-apply can apply a patch with a rename onto the original file(s).

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 Documentation/git-apply.txt       |    6 ++-
 builtin-apply.c                   |   17 +++++++-
 t/t4123-apply-renames-norename.sh |   85 +++++++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100755 t/t4123-apply-renames-norename.sh
Show changes to 3 files +105 −2

Documentation/git-apply.txt, builtin-apply.c, t/t4123-apply-renames-norename.sh

diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index 4c7e3a2..b691c55 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git-apply' [--stat] [--numstat] [--summary] [--check] [--index]
-	  [--apply] [--no-add] [--index-info] [-R | --reverse]
+	  [--apply] [--no-add] [--no-rename] [--index-info] [-R | --reverse]
 	  [--allow-binary-replacement | --binary] [--reject] [-z]
 	  [-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
 	  [--whitespace=<nowarn|warn|error|error-all|strip>]
@@ -121,6 +121,10 @@ discouraged.
 	the result with this option, which would apply the
 	deletion part but not addition part.
 
+--no-rename::
+	When applying patches with renames, this patch applies
+	the patch to the original file.
+
 --allow-binary-replacement, --binary::
 	Historically we did not allow binary patch applied
 	without an explicit permission from the user, and this
diff --git a/builtin-apply.c b/builtin-apply.c
index 25b1447..73134e8 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -41,11 +41,12 @@ static int apply_in_reverse;
 static int apply_with_reject;
 static int apply_verbosely;
 static int no_add;
+static int no_rename;
 static int show_index_info;
 static int line_termination = '\n';
 static unsigned long p_context = ULONG_MAX;
 static const char apply_usage[] =
-"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--no-rename] [--index-info]   [--allow-binary-replacement] [--reverse [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>]  <patch>...";
 
 static enum whitespace_eol {
 	nowarn_whitespace,
@@ -495,6 +496,8 @@ static int gitdiff_copydst(const char *line, struct patch *patch)
 
 static int gitdiff_renamesrc(const char *line, struct patch *patch)
 {
+	if (no_rename)
+		return 0;
 	patch->is_rename = 1;
 	patch->old_name = find_name(line, NULL, 0, 0);
 	return 0;
@@ -502,6 +505,8 @@ static int gitdiff_renamesrc(const char *line, struct patch *patch)
 
 static int gitdiff_renamedst(const char *line, struct patch *patch)
 {
+	if (no_rename)
+		return 0;
 	patch->is_rename = 1;
 	patch->new_name = find_name(line, NULL, 0, 0);
 	return 0;
@@ -2103,6 +2108,11 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
 	struct cache_entry *ce = NULL;
 	int ok_if_exists;
 
+	if (no_rename) {
+		new_name = old_name;
+		patch->new_name = old_name;
+	}
+
 	patch->rejected = 1; /* we will drop this after we succeed */
 
 	/*
@@ -2843,6 +2853,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 			no_add = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--no-rename")) {
+			no_rename = 1;
+			continue;
+		}
+
 		if (!strcmp(arg, "--stat")) {
 			apply = 0;
 			diffstat = 1;
diff --git a/t/t4123-apply-renames-norename.sh b/t/t4123-apply-renames-norename.sh
new file mode 100755
index 0000000..8c0d523
--- /dev/null
+++ b/t/t4123-apply-renames-norename.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Robin Rosenberg
+#
+
+test_description='git apply --no-rename.
+
+'
+
+. ./test-lib.sh
+
+# setup
+
+mkdir -p klibc/arch/x86_64/include/klibc
+
+cat >klibc/arch/x86_64/include/klibc/archsetjmp.h <<\EOF
+/*
+ * arch/x86_64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+  unsigned long __rbx;
+  unsigned long __rsp;
+  unsigned long __rbp;
+  unsigned long __r12;
+  unsigned long __r13;
+  unsigned long __r14;
+  unsigned long __r15;
+  unsigned long __rip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
+EOF
+
+cat >patch <<\EOF
+diff --git a/klibc/arch/x86_64/include/klibc/archsetjmp.h b/include/arch/m32r/klibc/archsetjmp.h
+similarity index 66%
+rename from klibc/arch/x86_64/include/klibc/archsetjmp.h
+rename to include/arch/m32r/klibc/archsetjmp.h
+--- a/klibc/arch/x86_64/include/klibc/archsetjmp.h
++++ b/include/arch/m32r/klibc/archsetjmp.h
+@@ -1,21 +1,21 @@
+ /*
+- * arch/x86_64/include/klibc/archsetjmp.h
++ * arch/m32r/include/klibc/archsetjmp.h
+  */
+
+ #ifndef _KLIBC_ARCHSETJMP_H
+ #define _KLIBC_ARCHSETJMP_H
+
+ struct __jmp_buf {
+-  unsigned long __rbx;
+-  unsigned long __rsp;
+-  unsigned long __rbp;
++  unsigned long __r8;
++  unsigned long __r9;
++  unsigned long __r10;
++  unsigned long __r11;
+   unsigned long __r12;
+   unsigned long __r13;
+   unsigned long __r14;
+   unsigned long __r15;
+-  unsigned long __rip;
+ };
+
+ typedef struct __jmp_buf jmp_buf[1];
+
+-#endif /* _SETJMP_H */
++#endif /* _KLIBC_ARCHSETJMP_H */
+EOF
+
+find klibc -type f -print | xargs git update-index --add --
+
+test_expect_success 'apply rename patch, without doing rename' \
+'git apply --no-rename patch &&
+git diff --numstat >stat.diff &&
+test "$(cat stat.diff)" = "6	6	klibc/arch/x86_64/include/klibc/archsetjmp.h"
+'
+
+test_done
-- 
1.5.3.1.g80926
Robin Rosenberg· Sep 26, 2007, 22:31 UTC · re: Robin Rosenberg · lore

Re: [PATCH] Add --no-rename to git-apply

onsdag 26 september 2007 skrev Robin Rosenberg:
> With this option git-apply can apply a patch with a rename
> onto the original file(s).

The reason (off the record) is that I use it for exporting to another more expen$ive SCM, that does rename tracking so I need to keep the file with the original name until telling the other SCM to rename the file. It may be useful for others doing similar things.

-- robin
Junio C Hamano· Sep 27, 2007, 05:12 UTC · re: Robin Rosenberg · lore

Re: [PATCH] Add --no-rename to git-apply

Robin Rosenberg <robin.rosenberg@dewire.com> writes:
> With this option git-apply can apply a patch with a rename
> onto the original file(s).

This is troubling from both design and implementation point of view.

 * Why would this be useful?  What's the point of producing the
   renaming patch if you know you would want to apply while
   ignoring the rename?
 * The change looks too special purpose to me.  If you are
   giving the ability to deposit the result to somewhere other
   than where the patch intendes to, why limit it only to the
   preimage name?  Aren't there cases where A is renamed to B
   sometime in the history, and you have a patch that talks
   about the content change A->A but the tree you have has the
   contents already in B, and you would want to apply that
   patch?  It feels that this and your "ignore rename" could be
   handled much more cleanly and flexibly by preprocessing the
   patchfile.
 * By disabling the parsing of rename header lines, you are
   disabling the sanity checking of the input done in
   gitdiff_verify_name() called from gitdiff_oldname() and
   gitdiff_newname().  I think it is wrong for --no-rename
   option to affect the parsing of the input.  If we were to do
   this, perhaps write_out_results() or one of its callee would
   be a better place to do so.
Johannes Schindelin· Sep 27, 2007, 10:24 UTC · re: Junio C Hamano · lore

Re: [PATCH] Add --no-rename to git-apply

Hi,
On Wed, 26 Sep 2007, Junio C Hamano wrote:
Show 11 quoted lines
> Robin Rosenberg <robin.rosenberg@dewire.com> writes:
> 
> > With this option git-apply can apply a patch with a rename
> > onto the original file(s).
> 
> This is troubling from both design and implementation point of
> view.
> 
>  * Why would this be useful?  What's the point of producing the
>    renaming patch if you know you would want to apply while
>    ignoring the rename?

Robin said in a follow-up mail that he needs it for a payed-for SCM (let's describe it as TransparentBox here), which insists on explicit renames.

But I suggest a simple script here which extracts from the diff the renames, which outputs a script which renames the file(s) back and then uses the TransparentBox' mv command:

sed -n -e "/^rename from/N" \
  -e "s/^rename from \(.*\)\nrename to \(.*\)/mv \2 \1 \&\& tb mv \1 \2/p" \
  < diff.patch

Ciao, Dscho

Robin Rosenberg· Sep 27, 2007, 19:04 UTC · re: Johannes Schindelin · lore

Re: [PATCH] Add --no-rename to git-apply

torsdag 27 september 2007 skrev Johannes Schindelin:
Show 12 quoted lines
> Robin said in a follow-up mail that he needs it for a payed-for SCM 
> (let's describe it as TransparentBox here), which insists on explicit 
> renames.
> 
> But I suggest a simple script here which extracts from the diff the 
> renames, which outputs a script which renames the file(s) back and then 
> uses the TransparentBox' mv command:
> 
> sed -n -e "/^rename from/N" \
>   -e "s/^rename from \(.*\)\nrename to \(.*\)/mv \2 \1 \&\& tb mv \1 \2/p" \
>   < diff.patch
> 

I tried something like that (integrated in the script), and the bugger noticed it and refused to work as exepected, but now that I think about it should be possible to fool it. I have to give it a go again and see what really actually went wrong.

-- robin
Robin Rosenberg· Sep 27, 2007, 19:12 UTC · re: Junio C Hamano · lore

Re: [PATCH] Add --no-rename to git-apply

torsdag 27 september 2007 skrev Junio C Hamano:
Show 11 quoted lines
> Robin Rosenberg <robin.rosenberg@dewire.com> writes:
> 
> > With this option git-apply can apply a patch with a rename
> > onto the original file(s).
> 
> This is troubling from both design and implementation point of
> view.
> 
>  * Why would this be useful?  What's the point of producing the
>    renaming patch if you know you would want to apply while
>    ignoring the rename?

The point of producing the rename info is to find out which renames are in it. It's only that I don't want to perform them straight away.

Show 10 quoted lines
>  * The change looks too special purpose to me.  If you are
>    giving the ability to deposit the result to somewhere other
>    than where the patch intendes to, why limit it only to the
>    preimage name?  Aren't there cases where A is renamed to B
>    sometime in the history, and you have a patch that talks
>    about the content change A->A but the tree you have has the
>    contents already in B, and you would want to apply that
>    patch?  It feels that this and your "ignore rename" could be
>    handled much more cleanly and flexibly by preprocessing the
>    patchfile.

Well it is special *purpose*, but not tied to a particuar tool. I'm not sure whether it is necessary with other tools though. I'll consider the preprocessing and will retry the rename-back that Johannes suggested.

Show 8 quoted lines
> 
>  * By disabling the parsing of rename header lines, you are
>    disabling the sanity checking of the input done in
>    gitdiff_verify_name() called from gitdiff_oldname() and
>    gitdiff_newname().  I think it is wrong for --no-rename
>    option to affect the parsing of the input.  If we were to do
>    this, perhaps write_out_results() or one of its callee would
>    be a better place to do so.

Hopefully git produces sane things so the checking shouldn't be that important, but I also do a check before beginning with checkouts and so on, much like git-cvsexportcommit. The check is performed without the switch.

-- robin

← back to recent threads