如何从同级目录中进行 git Cherry-pick ?

发布于 2024-11-01 05:28:35 字数 668 浏览 4 评论 0原文

我想使用 gitcherry-pick 将提交从一个文件应用到另一个文件而不进行重命名检测(许多类似的文件会导致错误的检测)。

(主)目录1/文件

(主)目录2/文件

但我不知道如何告诉cherry-pick相应的目录。

我有另一个案例,它与 git-1.7.5.rc1 配合得很好,现在支持合并策略,又名 -Xsubtree=.

(主)目录1/文件

(分支)文件

我调用了

git cherry-pick --no-commit -Xsubtree=directory1 branch~95

,它工作正常,将(branch~95)文件的更改更改为(master)directory1/file,而无需重命名检测。

对于第一种情况,我尝试使用 -Xsubtree=../directory1 调用 gitcherry-pick ,但这不起作用。我想我必须以某种方式告诉 gitcherry-pick 离开目录 2,然后转到目录 1 来应用补丁。

有人有解决这个问题的办法吗?

I would like to use git cherry-pick to apply a commit from one file to another without rename detection (to many similar files lead to wrong detections).

(master) directory1/file

(master) directory2/file

But I don't know how to tell cherry-pick the corresponding directory.

I had another case where it worked fine with git-1.7.5.rc1 which now supports merge strategies aka -Xsubtree=.

(master) directory1/file

(branch) file

I called

git cherry-pick --no-commit -Xsubtree=directory1 branch~95

and it worked fine, taking the changes from (branch~95) file to (master) directory1/file without rename detection.

For the first case I tried calling git cherry-pick with -Xsubtree=../directory1 but that did not work. I guess I would have to tell git cherry-pick somehow to leave the directory2 and then go to directory1 to apply the patches.

Does anyone have a solution for this problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何时共饮酒 2024-11-08 05:28:35

乍一看

git-read-tree

对于子树,我会看看

git read-tree -u --prefix dir1/ HEAD:dir2

这不会进行合并(git read-tree --merge 不支持 --prefix 同时...)

手动解决方案

否则,最好的 这可能

basecommitish='HEAD^'
git show "$basecommitish":dir1/a" > /tmp/a.orig
git show HEAD:dir2/b > /tmp/b.new
git merge-file dir1/a /tmp/a.orig /tmp/b.new    

适用于我的测试存储库,从而正确合并对 dir1/adir2/b 的更改。

检测基本修订版

不幸的是,为合并找到正确的基本修订版可能是一个挑战,因为 git merge-base 不适用于除提交 ID 之外的其他对象引用。

查找文件相同的最后一个修订版

因此,这里有一个片段,可帮助您开始查找两个文件同步的修订版(仅查看内容):

git rev-list HEAD | while read sha1
do 
    blob1=$(git rev-list --objects $sha1:dir1/a) 
    blob2=$(git rev-list --objects $sha1:dir2/b)

    echo $sha1: $blob1 $blob2
    if [ "$blob1" == "$blob2" ]; 
    then 
        echo Match; 
        break; 
    fi
done

我的 testrepo 上的输出:

c5a6b97712d9ebd49146dad6523b2bbc33aea7c0: 4ce3b294e6408ace53b50127aafb2c9308caacf1 e913153db7650d7b8e947066652cf21388552812
7b75768fd3434c867d3741cf07044bf04ef1cc79: 03b82631ac519bf10c20bb12d3b1b03b872dd087 03b82631ac519bf10c20bb12d3b1b03b872dd087
Match

您可以轻松包含可能存在的任何修订版在其他分支上,将 git rev-list HEAD 替换为 git rev-list --all 。

查找文件相同的一对修订版

更高级的脚本将通过执行嵌套循环来查找不匹配修订版中的匹配内容

function findblobs() 
{
    for path in "$@"; 
    do 
        git rev-list HEAD | while read sha1
        do 
            echo $sha1 $(git rev-list --objects "$sha1:$path")
        done | uniq -f 1
    done
}

来查找相同的信息

findblobs dir1/a dir2/b | sort -k2 | uniq -Ddf 1

// output on testrepo again:
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087

// force multiple hits across several revisions:
git show 7b75768fd3:dir1/a > dir2/b && git commit -am 'force synch with 7b75768fd3'

findblobs dir1/a dir2/b | sort -k2 | uniq -Ddf 1

// output is now:
46b8748f121f8842d936994fa09ad1a81b35d3cc 03b82631ac519bf10c20bb12d3b1b03b872dd087
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087

现在,您可以通过执行“Since sort(1) 使用稳定排序,您可以依赖第一个提交哈希来对应于此示例调用中的 dir1/a,第二个提交哈希对应于 dir2/b注意调用 findblobs 时的顺序)

At a glance

git-read-tree

For subtrees, I'd look at

git read-tree -u --prefix dir1/ HEAD:dir2

This will not do a merge (git read-tree --merge does not support the --prefix simultaneously...)

manual solution

Otherwise, the best you can do, is probably

basecommitish='HEAD^'
git show "$basecommitish":dir1/a" > /tmp/a.orig
git show HEAD:dir2/b > /tmp/b.new
git merge-file dir1/a /tmp/a.orig /tmp/b.new    

This worked for my test repository resulting in correct merge with changes to both dir1/a and dir2/b.

Detecting base revisions

Unfortunately, finding the correct basse revision for the merge can be a challenge, as git merge-base won't work for other object references than commit ids.

Finding last revision where the files were identical

So here is a snippet that will get you started in finding a revision where both files were in synch (looking at the contents only):

git rev-list HEAD | while read sha1
do 
    blob1=$(git rev-list --objects $sha1:dir1/a) 
    blob2=$(git rev-list --objects $sha1:dir2/b)

    echo $sha1: $blob1 $blob2
    if [ "$blob1" == "$blob2" ]; 
    then 
        echo Match; 
        break; 
    fi
done

Output on my testrepo:

c5a6b97712d9ebd49146dad6523b2bbc33aea7c0: 4ce3b294e6408ace53b50127aafb2c9308caacf1 e913153db7650d7b8e947066652cf21388552812
7b75768fd3434c867d3741cf07044bf04ef1cc79: 03b82631ac519bf10c20bb12d3b1b03b872dd087 03b82631ac519bf10c20bb12d3b1b03b872dd087
Match

You can easily include any revisions that might exist on other branches by replacing git rev-list HEAD by git rev-list --all.

Finding a pair of revisions where the files were identical

A more advanced script that will look for matching contents in non-matching revisions by doing nested loops would be

function findblobs() 
{
    for path in "$@"; 
    do 
        git rev-list HEAD | while read sha1
        do 
            echo $sha1 $(git rev-list --objects "$sha1:$path")
        done | uniq -f 1
    done
}

Now you can find the same info by doing

findblobs dir1/a dir2/b | sort -k2 | uniq -Ddf 1

// output on testrepo again:
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087

// force multiple hits across several revisions:
git show 7b75768fd3:dir1/a > dir2/b && git commit -am 'force synch with 7b75768fd3'

findblobs dir1/a dir2/b | sort -k2 | uniq -Ddf 1

// output is now:
46b8748f121f8842d936994fa09ad1a81b35d3cc 03b82631ac519bf10c20bb12d3b1b03b872dd087
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087
7b75768fd3434c867d3741cf07044bf04ef1cc79 03b82631ac519bf10c20bb12d3b1b03b872dd087

Since sort(1) uses a stable sort, you can rely on the first commit hash to correspond to dir1/a and the second one to dir2/b in this sample call (note the ordering in the call to findblobs)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文