假设补丁是从过去的特定提交创建的,不再适用于HEAD。
如何在HEAD历史记录中找到第一个或更好的最后一次提交,此修补程序适用于“git apply”? 也许git bisect的东西?但是哪个命令会告诉我补丁是否适用?
理想情况下,我想回到该提交,应用补丁,然后重新绑定或与原始HEAD合并,再次diff以创建新补丁,除非发生冲突。 在此之后,我想回到最初的HEAD,所以我可以继续使用更多的补丁。
背景:有许多补丁需要重新加载...... (是的,有生态系统补丁仍然是一个东西..)
答案 0 :(得分:2)
此答案假定修补程序是使用git diff
创建的,而不是git format-patch
,并且git log
的默认寻呼机为less
。
以下是从git diff <sha1> <sha2>
,
diff --git a/osx/.bash_profile b/osx/.bash_profile
index c7b41df..fb80367 100644
--- a/osx/.bash_profile
+++ b/osx/.bash_profile
@@ -3,6 +3,10 @@
# Setup PATH for Homebrew packages
export PATH=/usr/local/bin:$PATH
+# Setup Scala variables
+export SCALA_HOME=/usr/local/Frameworks/scala # Symlinked directory
+export PATH=$PATH:$SCALA_HOME/bin
+
# Initialize rbenv,
# https://github.com/sstephenson/rbenv#homebrew-on-mac-os-x
eval "$(rbenv init -)"
采取这一行:
+export SCALA_HOME=/usr/local/Frameworks/scala # Symlinked directory
并在git log --patch
或git log -p
中搜索。在/
中输入less
,然后输入您要搜索的正则表达式:
/\+export SCALA_HOME=/usr/local/Frameworks/scala # Symlinked directory
此处+
使用\
进行转义,因为它是正则表达式中的特殊字符。按Enter键查找第一个匹配项,然后按n
调出下一个匹配项,或N
进入上一个匹配项。
这将帮助您找到可能适用于修补程序来源的提交。您还可以使用less
中的空格键向下翻页,并b
进行翻页。
答案 1 :(得分:1)
git apply --3way
应该使用blob哈希定位每个文件的基本版本,并一步一步合并所有文件,假设它们存在于您的回购历史记录中,并且您可以处理合并冲突。对于许多人来说,这可能是一个更简单的解决方案。
如果您仍然真的想知道包含diff的基本文件的历史提交,则下面的脚本将locate commits containing a single blob hash的解决方案之一扩展为尝试查找包含从中提取的一组blob哈希值的提交补丁文件。
#!/bin/sh
# git-find-patch-base takes a patch produced by "git diff" and tries to locate commit(s)
# containing all source blobs
# The first parameter is the name of the patch file to examine
patch_file="$1"
# Any remaining parameters are passed as a group to the git log command using $@ below
shift
# Make a temporary file and capture a list of all the starting
# file blob hashes that the patch used in it. Note: Adding a file shows
# a starting hash of 00000000, so we filter that one out...
tmp_blob_file=$(mktemp)
echo "Examining patch file \"$patch_file\"..." 1>&2
grep -E "^index" "$patch_file" | colrm 1 6 | colrm 10 | sort | uniq | grep -v 00000000 > "$tmp_blob_file"
# Count how many unique blob hashes we identified
blobcount=$(cat "$tmp_blob_file" | wc -l)
echo "Found $blobcount unique blob hashes in patch..." 1>&2
# Use git log to get a list of commits to check against. Then, for
# each of those commits, count how many of the blob hashes that we
# wanted appear in it, and output the commit hash if it's at least the
# ideal blob count. Note: this is an imperfect searching method, since
# there is a chance for hash collision, exacerbated since the grep is not
# forcing the short hashes to only match the beginning of the long
# hashes.
echo "Searching log/tree history of git..." 1>&2
git log "$@" --pretty=format:'%T %h %s' \
| while read tree commit subject ; do
if test $(git ls-tree -r "$tree" | grep -f "$tmp_blob_file" | wc -l) -ge "$blobcount" ; then
echo "$commit" "$subject"
break
fi
done
# Clean up the temporary file we made...
rm "$tmp_blob_file"
第一个参数是要分析的补丁文件的名称,所有剩余参数都传递给git log
,以帮助扩展/限制要检查的提交列表。如果要相对于特定分支进行第一次提交,则可以运行git-find-patch-base foo.patch branchname
。如果您完全不知道某物来自何处,则可以运行git-find-patch-base foo.patch --all
,然后边喝咖啡边做。 git日志上有很多有用的限制器,例如--grep
或--author
,可以加快此过程。
所示脚本在第一次循环中停止,而break
在while循环之外。您可以删除它,它将彻底搜索所有内容,并吐出所有候选提交。