I have a situation where I have switched a directory from being a subdirectory to being a submodule. I then try to cherry-pick a commit from a taskbranch that was made before the switch to the master branch. The commit touches a file outside the subdirectory/submodule. Yet "git cherry-pick" fails with this error message:
> error: could not apply 78c403e... Add a project feature > hint: after resolving the conflicts, mark the corrected paths > hint: with 'git add <paths>' or 'git rm <paths>' > hint: and commit the result with 'git commit'
I can resolve the situation by running "git add libfoo && git cherry-pick --continue". The generated commit contains no changes to "libfoo".
I don't understand why I need to manually add libfoo, as the commit I'm cherry-picking doesn't touch anything in libfoo.
The script below can reproduce the issue. Tested with git 2.15.1, 2.14.0 and 2.8.0, all with the same result.
Is this a bug in "git cherry-pick"?
-- cut here for cherry-across-submodule -- #!/bin/sh # # This script creates a simple repo, where the "libfoo" directory # initially is a normal directory, but later becomes a git submodule. # It then tries to cherry-pick a commit (that doesn't touch libfoo) # that was created before the conversion to master (after the # conversion). This fails for unclear reasons.
# I've tested this with the following git versions: # - 2.8.0 # - 2.14.0 # - 2.15.1 # # They all behave the same
# export PATH=/usr/local/git-2.15.1/bin:$PATH
set -e -x
git --version
# Refuse to run if this directory already exists, to prevent data loss. mkdir cherry-across-submodule-root cd cherry-across-submodule-root
mkdir root (cd root && git init --bare libfoo.git) (cd root && git init --bare project.git)
mkdir workspace (cd workspace && git clone ../root/libfoo) (cd workspace && git clone ../root/project)
proj_commit ()
{
(cd workspace/project &&
printf "$1\n" >> $2 &&
git add $2 &&
git commit -m"$3")
}foo_commit ()
{
(cd workspace/libfoo &&
printf "$1\n" >> $2 &&
git add $2 &&
git commit -m"$3")
}both_commit ()
{
foo_commit "$1" $2 "$3"
proj_commit "$1" libfoo/$2 "Imported libfoo: $3"
}proj_commit "This is a project" README "Started the project" mkdir workspace/project/libfoo both_commit "This is a library" README "Started the library" both_commit "all:\n\ttouch libfoo.a" Makefile "Build something" proj_commit "all:\n\tmake -C libfoo" Makefile "Build libfoo" proj_commit "ceder" AUTHORS "I made this" both_commit "GPL" "COPYING" "Add license info" (cd workspace/libfoo && git push) (cd workspace/project && git push) (cd workspace/project && git checkout -b task-1) proj_commit "int feature() { return 17; }" feature.c "Add a project feature" (cd workspace/project && git push -u origin task-1)
assert_clean()
{
(cd workspace/project &&
[ -z "`git status --porcelain`" ] )
}# Cherrypicking task-1 to task-2 works fine. (cd workspace/project && git checkout -b task-2 master && git cherry-pick task-1) assert_clean
(cd workspace/project &&
git checkout master &&
git rm -r libfoo &&
git submodule add -b master ../libfoo.git libfoo &&
git commit -m"Made libfoo a submodule")
assert_clean# Now suddenly cherrypicking fails? I get this message from the # cherry-pick command:
# error: could not apply 78c403e... Add a project feature # hint: after resolving the conflicts, mark the corrected paths # hint: with 'git add <paths>' or 'git rm <paths>' # hint: and commit the result with 'git commit'
(cd workspace/project && git checkout -b task-3 master && git cherry-pick task-1)
# At this point, "git status --porcelain" prints two lines: # A feature.c # AU libfoo
assert_clean -- cut here for cherry-across-submodule --
/ceder