Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

check if git apply was already applied

This question is about git apply

Is there a way to distinguish between: it failed because...

  1. ... the patch is already applied
  2. ... the source code is really different

The directory i work in is not a git directory, therefore i can't use git log or something else.

I know about the -R (reverse) option, therefore my current workaround is this:

git apply abc.patch || git apply abc.patch -R --check && echo already applied

This way git apply abc.patch -R --check && git apply abc.patch will only be executed if git apply abc.patch fails, it then checks if it failed because the patch is already applied (git apply abc.patch -R --check) and if this is the case, it echoes "already applied"

But i don't like it, isn't there someting like a builtin-solution in git's apply?

like image 476
ataraxis Avatar asked Jan 09 '18 12:01

ataraxis


2 Answers

The short answer is no, or at least, not generally.

Consider: a patch is a set of directions saying "remove this line" and "add these other lines". Suppose the patch for file reads, in its entirety:

diff --git a/file b/file
index 87cdbbd..3d8696b 100644
--- a/file
+++ b/file
@@ -7,4 +7,3 @@ this file is dull
 this file is dull
 this file is dull
 this file is dull
-this file is dull

In other words, the input file was very dull, at least towards the end, where it just kept repeating "this file is dull".

The change to the file was to delete one of those dull lines. The context is more, equally dull lines, followed by "end of file".

Since the patch was generated, someone modified the top of the file so that it's no longer just 10 (or 9) dull lines, but it still ends with at least four dull lines. The file is now over 50 lines long with most of the top ones pretty exciting, comparatively at least.

Can you, as a smart human, tell whether or not the patch to this file has been applied yet? All I will tell you is that the patch may or may not have been applied, along with the other changes that added many exciting lines at the top of the file.

If you can't tell, why would you believe Git can? I don't know about you, but I can't tell if the change that added the exciting lines also deleted the final dull one.

(Now, in some cases—especially if you have that index 87cdbbd..3d8696b 100644 line—there is a way to tell, provided that you also have a committed version of the file whose hash ID is 87cdbbd, because now we can extract that particular version of the file. But you haven't said whether you have the index line, and if so, whether you also have a blob with a matching hash ID.)

like image 123
torek Avatar answered Oct 09 '22 07:10

torek


Actually, git apply --reverse --check is the "built-in to git" solution you are looking for. For cases like the many identical lines as described in the other answer, all you need to do is make sure your patch file has more/enough context to disambiguate (e.g. with git diff -U60).

Example: if a patch says "remove one of these 50 identical lines leaving 49" there are well-defined outcomes:

  • With less than 49 of those lines or more than 50 of those lines, the patch does not apply: both get apply --check and git apply --reverse --check will fail.
  • With exactly 49 of those lines, the patch has already been applied: git apply --check will fail and git apply --reverse --check will succeed.
  • With exactly 50 of those lines, the patch hasn't been applied: git apply --check will succeed and git apply --reverse --check will fail.
  • If get apply --check and git apply --reverse --check both succeed, you need to increase the context for the patch to disambiguate.

You could even programmatically test repeatedly incrementing the context for the patch until it works as expected if you weren't doing it by hand.

like image 21
LB-- Avatar answered Oct 09 '22 07:10

LB--