Skip to content

Instantly share code, notes, and snippets.

@jimathyp
Last active March 3, 2022 01:52
Show Gist options
  • Save jimathyp/47da67869ea5fc36021c1e29275e5c3d to your computer and use it in GitHub Desktop.
Save jimathyp/47da67869ea5fc36021c1e29275e5c3d to your computer and use it in GitHub Desktop.
git patch

Git differences and patches

To create a diff file

git diff the_file > the_file.diff

To apply the diff (asusming file name is the same)

git apply the_file.diff

eg. on one branch and have made changes, but don't want to commit to that branch, or create a new branch.

  1. Create the diff file (no need to add and commit)

    git diff the_file > the_file.diff

  2. Change branches

    git checkout the_target_branch

  3. Apply the changes

    git apply the_file.diff

This command applies the patch but does not create a commit. Use git-am[1] to create commits from patches generated by git-format-patch[1] and/or received by email.

Other commands

sender:

git format-patch

receiver:

git am

(Also transfers the authorship info and the commit message)

Scenario

Have a feature branch. Changes made in main branch to a relevant file since the feature branch was created. Don't want to do a rebase (too many commits). Don't want to merge (too many commits).

Checking out the file directly doesn't seem to give desired outcome (PR merge conflicts?) ` git checkout master -- path/to/file.py `

Will try patch - get changes to a patch file, apply those changes, commit as a 'patch' commit, then PR.

` git diff main..feature/branch -- path/to/file.py `

Is not the right way - shows changes in main as subtractions - swap order of branches

` git diff feature/branch..main -- path/to/file.py `

Then just output to a file

` git diff feature/branch..main -- path/to/file.py > diff.patch `

Can't see diff of files added to Git or in stating, so use --staged or --cached option.

git diff filename changes of the current file to its previous commited state

git diff branch_name, compartes modifications of current branch to the mentioned branch

git diff commit_1 commit_2

Apply as above, git apply patch_file.patch

Exchanges code via patches isn't very common anymore. Basically export commits to a plain text file which can be sent to someone.

git format-patch creates patch files that includes all commits that are in the specified branch but not in the checked out branch

For a single file containing all patches,

git format-patch some_branch --stdout >> file.patch

Then use "git am patch" to apply

Applying changes from one branch to another, options:

  • merge branches in commit history, commits are on separate "branches" usually a merge commit is created. can do a "fast forward. " squash - a single commit with all pulled changes is created on top of the current branch can use no commit to inspect changes created by merge without committing
  • rebase branches commit history is on the same "branch" - single line applies the commits from one branch on top of the HEAD commit. can do interactive rebase do not use rebase on public branches
  • cherry-pick - apply separate commits from one branch to another

git-format-patch https://git-scm.com/docs/git-format-patch

git-am https://git-scm.com/docs/git-am "apply message" creates commits from patches generated by git-format-patch splits messages into commits, applies to the current branch

git-apply https://git-scm.com/docs/git-apply applies the patch but does not create a commit

git diff

I know master is more up to date

git diff feature_branch..master -- file.py

git diff feature_branch..master -- file.py > file.patch git apply dag.patch

git format-patch feature_branch --stdout >> branch.patch git am branch.patch

(on feature_branch)$ git am branch.patch Applying: Saving for now, switching to other DAGs .git/rebase-apply/patch:156: trailing whitespace.

...some_file

error: another_file: patch does not apply error: yet_another_file: does not exist in index Patch failed at 0001 Saving for now, switching to other DAGs

hint: Use 'git am --show-current-patch' to see the failed patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".

--stdout Print all commits to the standard output in mbox format, instead of creating a file for each one.

git format-patch feature_branch

git diff master_commit feature_branch > branch-diff.patch

master commit is from when the feraturebranch diverged ` git format-patch master_commit..feature_branch ` outputs individual patch files

now apply each patch file ` git am 0001.... `

Applying .... error: patch failed error: patch does not apply this patch doesn't apply because the file already contains the changes that are in the patch

git am --continue complains, no changes use git am --skip

note a .git/rebase-apply directory exists during the patch contains

0001 - the patch file abort-safety - a hash (de3c1731f in this case) which using git cat-file -p, it is a commit object and is the last patch (commit) that was applied apply-opt - empty applying - empty author-script - GIT_AUTHOR_NAME=... GIT AUTHOR_EMAIL GIT_AUTHOR_DATE final-commit - commit message info - appears to be commit author email, subject, date - but not exactly from the patch file keep - contains 'f' last - contains '1' messageid - 'f' msg - empty next - '1' patch - the full patch file with after the '---' and from/date/subject patch metadata quiet 'f' scissors empty sign 'f' threeway 'f' utf8 't'

Sources:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment