1

I got some problems to understand why the patch files generated by git diff are different.

Below is my git log: the local_tracking_branch has one extra feature which not been push to remote.

commit COMMIT_HASH_1 (HEAD -> local_tracking_branch)

commit COMMIT_HASH_2 (origin/mainline, origin/HEAD)

I use git diff mainline > patch1 to generate the first patch.

Then I use git diff COMMIT_HASH_1 COMMIT_HASH_2 > patch2 to generate the second patch.

It turns out that patch1 is larger than patch2 about 10K bytes.

A more context here, I am instructed to use the first approach to generate the patch for release, but I am wondering it is ok to use second approach to generate the patch file.

A another scenario is that once I push the feature into remote mainline, is it ok that I could use second approach git diff commmit-hash1 commit-hash2 to generate the valid patch?

Thank for the explanation.

1
  • Use better tool, i.e. git format-patch. Commented Mar 28, 2020 at 11:20

1 Answer 1

2

I use git diff mainline

This form of git diff compares the given commit—the hash ID will be the result of running:

git rev-parse mainline

which may well be quite different from that of:

git rev-parse origin/mainline

—to the current work-tree. More precisely, it compares the saved snapshot in the given commit, to the current work-tree (the files you can see).

I use git diff COMMIT_HASH_1 COMMIT_HASH_2

This form of git diff compares the saved snapshot in the first commit to that in the second.

Given these fragments of output from git log:

commit COMMIT_HASH_1 (HEAD -> local_tracking_branch)
commit COMMIT_HASH_2 (origin/mainline, origin/HEAD)

we can predict that mainline resolves to a third commit hash. We cannot say for sure whether your current work-tree matches the saved snapshot in COMMIT_HASH_1, but if git status says that everything is "clean" and there is nothing to commit, it probably does match that.

So the most likely source of all the oddness is that mainline refers to some third commit whose snapshot is not much like the snapshot in the commit to which the name origin/mainline resolves. (You already have that hash ID, but to see it again, by itself, use the earlier-mentioned git rev-parse origin/mainline.) But another possibility is that the current work-tree is different from any and/or all of these other commits. Since the work-tree consists of ordinary files, any of your ordinary (non-Git) commands can make any arbitrary changes they like to these ordinary files.

A another scenario is that once I push the feature into remote mainline, is it ok that I could use second approach git diff commmit-hash1 commit-hash2 to generate the valid patch?

You can do this any time you like. How valid it is depends on who has which commit and what they want to do with those commits.

The thing to keep in mind is that names can change over time. A name like mainline or origin/mainline refers to some commit by hash ID. You can find out which one they name right now using git rev-parse. Tomorrow, after people do things with branches, they may refer to different commit hash IDs.

The hash IDs, however, remain fixed forever. Given any particular hash ID, that hash ID represents that commit. No other commit can ever have that hash ID. The snapshot for that commit is frozen for all time; that hash ID will always represent those files, in that form.

Hash IDs are long and ugly and random-looking and very hard to type in. That's one reason we use names. Branch names, however, change over time. That's one reason we use tag names: tag names are designed to be stable, to not-change over time. Use a commit hash; or, use a tag name to specify one particular commit, and don't move tag names around manually (Git won't move them on its own) and you have a steady way to refer to that particular commit.

Sign up to request clarification or add additional context in comments.

3 Comments

so git diff origin/mainline and git diff mainline are two different things here? Thank you.
In this case, yes. Had they been the same thing, you would have seen, not commit COMMIT_HASH_2 (origin/mainline, origin/HEAD) but rather commit COMMIT_HASH_2 (mainline, origin/mainline, origin/HEAD).
If you git checkout mainline and then git merge --ff-only origin/mainline and this succeeds, your mainline and your origin/mainline will match. Whether and when to do this is up to you. There are conditions under which it won't succeed; whether this is good, bad, or indifferent is also up to you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.