michael
michael

Reputation: 110600

Get error message ''fatal: sha1 information is lacking or useless" when apply a patch using "git am -3"

I am trying to apply a series of patches from 1 git repository to another git repository using git am -3 "path to a patch". I apply them in order, from patch 1-4, it works fine.

But when I come to 5th patch,I get the error saying "fatal: sha1 information is lacking or useless". I go the to git repository where I apply the patch, I do see the file 'dev/afile'. So I wonder why git is complaining about "sha1 information is lacking or useless (dev/afile.c)" and how can I fix my problem?

 $ git am -3 ~/Tmp/mypatches/0005-fifth.patch
Applying: rpmsg: Allow devices to use custom buffer allocator
fatal: sha1 information is lacking or useless (dev/afile.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 first patch
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".

And why it said "Patch failed at 0001 first patch", when I do "git am -3 ~/Tmp/mypatches/0005-fifth.patch", it completes with no error.

Thank you.

Upvotes: 47

Views: 36397

Answers (10)

Ivan Yuzafatau
Ivan Yuzafatau

Reputation: 620

You can also try:

git am -C0 <patch>

For example:

git am -C0 example.patch

Upvotes: 4

dpat
dpat

Reputation: 303

The patch fails because it was not created against the correct source tree (see: https://stackoverflow.com/a/27998109/2142030).

E.g. you want to export the following commit from 'the other' repository:

❯ git log --pretty=on --no-decorate -1 
e3460be scripts/upgrade.sh: Show disk usage and ask for conformation

❯ git format-patch -1
0001-scripts-upgrade.sh-Show-disk-usage-and-ask-for-confo.patch

Then, if you want to import this commit, it fails:

❯ git am 0001-scripts-upgrade.sh-Show-disk-usage-and-ask-for-confo.patch
Applying: scripts/upgrade.sh: Show disk usage and ask for conformation                                   
error: sha1 information is lacking or useless (upgrade.sh).                                              
error: could not build fake ancestor                                                                     
Patch failed at 0001 scripts/upgrade.sh: Show disk usage and ask for conformation

Only after git am you patch the fail manually:

❯ patch -p0 < 0001-scripts-upgrade.sh-Show-disk-usage-and-ask-for-confo.patch
patching file scripts/upgrade.sh                                                                         
Hunk #1 succeeded at 27 (offset -4 lines).   

If you get failed hunks, check the rejects file (e.g. scripts/upgrade.sh.rej) and review and fix the problem:

[...]
patching file scripts/upgrade.sh                                                                                                                                                                                   
Hunk #1 FAILED at 29.                                                                                                                                                                                              
Hunk #2 succeeded at 113 (offset -4 lines).                                                              
1 out of 2 hunks FAILED -- saving rejects to file scripts/upgrade.sh.rej

❯ vim scripts/upgrade.sh scripts/upgrade.sh.rej

After that, add the file and continue the am:

❯ git add scripts/upgrade.sh
❯ git am --continue                                                        
Applying: scripts/upgrade.sh: Show disk usage and ask for conformation

Now, you not only have patched the file (like in https://stackoverflow.com/a/49537226/2142030) but you also have imported the original commit (with a different sha).

❯ git log --pretty=on --no-decorate -1 
102ad06 scripts/upgrade.sh: Show disk usage and ask for conformation

Upvotes: 0

Li Chen
Li Chen

Reputation: 5270

Maybe this is a git's bug. Finally I use cherry-pick instead and resolve conflicitions.

Upvotes: 0

EddiG
EddiG

Reputation: 202

If you are sure that the patch could be applied without worries about the surrounding context of the changes you could tell to ignore any context using this command git am -C0 your.patch

From the Docs:

-C<n>
Ensure at least lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default, no context is ever ignored.

Upvotes: 2

nicomen
nicomen

Reputation: 1203

I have gotten similar conflicts, and an nth solution that worked for me was to:

  1. show the current patch failing to apply
  2. find the original commit hash/checksum/id
  3. go to the repository I am copying the patches from
  4. check out the commit before the one I failed to apply
  5. copy over the affected files as-is
  6. add the now changed files
  7. continue the applying process:
new_repo> git am -3 /tmp/bunchopatches/*
# 10: ERROR happens
new_repo> git am --show-current-path | head -n 1
# From fe89d2a53ccf30d068fdd5596a325f06b74ec4af Mon Sep 17 00:00:00 2001
orig_repo> git checkout fe89d2a53ccf30d068fdd5596a325f06b74ec4af^
orig_repo> cp aff/ected/files/* /new_repo/aff/ected/files/
new_repo> git add aff/ected/files/*
new_repo> git am --continue
# rince and repeat (goto 10)

(If you do the orig_repo> commands in a separate window this can actually be a rather quick process, just applied 80 patches with about 10 spacing conflicts this way=

Upvotes: 1

Russell Gallop
Russell Gallop

Reputation: 1699

I had this when trying to apply patches from one repository into one which had unrelated history (the same project but with rebuilt git history). The reason you get the message fatal: sha1 information is lacking or useless (dev/afile.c) is that when git is trying to do a 3 way merge it needs to access the state of that file. Those files are pointed to by the hashes in the format patch output (e.g.)

diff --git a/dev/afile.c b/dev/afile.c
index ebbd50fc0b7..ef1ca87ead0 100644
--- a/dev/afile.c
+++ b/dev/afile.c

ebbd50fc0b7 and ef1ca87ead0 refer to hashes of the content of the files, not commit hashes.

If you try:

git cat-file blob <hash from patch>

Git will report:

fatal: Not a valid object name <hash from patch>

Git can't find them because those versions of the file are not available in your local repository (hence the message Repository lacks necessary blobs to fall back on 3-way merge.). You can make those objects available in your local repository with:

git remote add old_repo <url>
git fetch old_repo

Now, when you run:

git cat-file blob <hash from patch>

You should be given the contents of that file. Now try your git am command again and it should be able to do 3 way merges.

Upvotes: 17

Pini Cheyni
Pini Cheyni

Reputation: 5437

Just did the following and was able to solve this issue:

patch -p1 < example.patch

Upvotes: 20

Tyler Swartzenburg
Tyler Swartzenburg

Reputation: 61

I ran into this issue when I tried to create the patch while on the wrong branch.

I thought "git format-patch ..." would be able to determine what I wanted because you can specify the main branch and the branch you want to patch in the format-patch call. I realized it was wrong because it was mentioning commits that were part of a branch that didn't exist on the site I was patching to.

Long story short, make sure you are on the branch you want to patch when you create the patch.

Upvotes: 3

jonasl
jonasl

Reputation: 353

Are you using submodules in your project?

There was a bug in git 1.7.12 to 1.8.1.2 where an updated submodule would cause a rebase (or patch) to fail with the error message:

fatal: sha1 information is lacking or useless

leaving the commit empty if applied.

More info here.

Updating git to version 1.8.4 solves this problem

Upvotes: 10

Kornel
Kornel

Reputation: 100170

The patch file starting with 0001- cannot be applied cleanly - there is some conflict.

Git wanted to resolve that conflict by looking at commits this patch has been based on, but you don't have those commits in your repository.

Probably the patch has been created from a branch that had commits that were never shared, or either your or submitter's branch has been rebased.

It doesn't matter that patch 0005- can be applied with no error. The error is about 0001- specifically.

Upvotes: 13

Related Questions