Git多次使用Bash进行cherry-pick时出现错误。

huangapple go评论94阅读模式
英文:

Git multi cherry pick with Bash throwing error

问题

以下是翻译好的部分:

我正在尝试一次性实现多个提交ID的Git挑选操作。
但是它失败了,要么这不是它的正确使用方式。

我正尝试使用这里的bash命令:https://stackoverflow.com/a/2553705/9614476

#!/bin/bash

if [ -z $1 ]; then
    echo "相当于对指定范围内的每个提交运行git-cherry-pick。";
    echo "";
    echo "用法: $0 start^..end";
    echo "";
    exit 1;
fi

git rev-list --reverse --topo-order $1 | while read rev
do
  git cherry-pick $rev || break
done

我创建了一个Ant目标,类似于这样:

<target name="git_multi_cherry_pick">
    <echo message="开始:MultiMerge"/>
    <exec executable="C:\Program Files\Git\bin\bash.exe" osfamily="windows" failonerror="true">
        <arg value="${gitMultiCherryPick}"/>
        <arg value="${gitCommitIds}"/>
    </exec>
    <exec executable="/bin/bash" osfamily="unix" failonerror="true">
        <arg value="${gitMultiCherryPick}"/>
        <arg value="${gitCommitIds}"/>
    </exec>
</target>

我正在使用Java中的AntExecutor来调用上述目标。
AntExecutor的代码可以在这里找到 - https://github.com/asciidoctor/asciidoctor-ant/blob/master/src/test/java/org/asciidoctor/ant/AntExecutor.java

Map<String, String> propertiesMap = new HashMap<>();
propertiesMap.put("gitMultiCherryPick", "git-multi-cherry-pick.sh");
propertiesMap.put("gitCommitIds", "204a3e81712000d09a2794cc4ef1d090c4280f4e,9c5242d6a15b14032e9fc1f408be3c91026b1e1f");
List<String> sf_build = AntExecutor.executeAntTask("完整路径 \\resources\\build\\build.xml",
        "git_multi_cherry_pick", propertiesMap);

但是它失败并显示以下错误:

执行文件和参数周围的'字符不是命令的一部分,204a3e81712000d09a2794cc4ef1d090c4280f4e,9c5242d6a15b14032e9fc1f408be3c91026b1e1f, git-multi-cherry-pick.sh, 致命错误:模糊参数'204a3e81712000d09a2794cc4ef1d090c4280f4e,9c5242d6a15b14032e9fc1f408be3c91026b1e1f':

我认为这不是我们传递commitIds的正确方式。有没有人在之前使用过上述的bash脚本?

英文:

I am trying to implement Git cherry pick for multiple commit Ids at once.
But it fails, or either this is not how it should be used.

I am trying to use bash command from here : https://stackoverflow.com/a/2553705/9614476

  #!/bin/bash
  
  if [ -z $1 ]; then
      echo &quot;Equivalent to running git-cherry-pick on each of the commits in the range specified.&quot;;
      echo &quot;&quot;;
      echo &quot;Usage:  $0 start^..end&quot;;
      echo &quot;&quot;;
      exit 1;
  fi
  
  git rev-list --reverse --topo-order $1 | while read rev
  do
    git cherry-pick $rev || break
  done

I created a target for ant like this :

&lt;target name=&quot;git_multi_cherry_pick&quot;&gt;
    &lt;echo message=&quot;START: MultiMerge&quot;/&gt;
    &lt;exec executable=&quot;C:\Program Files\Git\bin\bash.exe&quot; osfamily=&quot;windows&quot; failonerror=&quot;true&quot;&gt;
        &lt;arg value=&quot;${gitMultiCherryPick}&quot;/&gt;
        &lt;arg value=&quot;${gitCommitIds}&quot;/&gt;
    &lt;/exec&gt;
    &lt;exec executable=&quot;/bin/bash&quot; osfamily=&quot;unix&quot; failonerror=&quot;true&quot;&gt;
        &lt;arg value=&quot;${gitMultiCherryPick}&quot;/&gt;
        &lt;arg value=&quot;${gitCommitIds}&quot;/&gt;
    &lt;/exec&gt;
&lt;/target&gt;

And I am using AntExecutor from Java to call the above target.
AntExecutor code can be found here - https://github.com/asciidoctor/asciidoctor-ant/blob/master/src/test/java/org/asciidoctor/ant/AntExecutor.java

        Map&lt;String, String&gt; propertiesMap = new HashMap&lt;&gt;();
        propertiesMap.put(&quot;gitMultiCherryPick&quot;, &quot;git-multi-cherry-pick.sh&quot;);
        propertiesMap.put(&quot;gitCommitIds&quot;, &quot;204a3e81712000d09a2794cc4ef1d090c4280f4e,9c5242d6a15b14032e9fc1f408be3c91026b1e1f&quot;);
        List&lt;String&gt; sf_build = AntExecutor.executeAntTask(&quot;FullPath \\resources\\build\\build.xml&quot;,
                &quot;git_multi_cherry_pick&quot;, propertiesMap);

But it fails with this error :

The &#39; characters around the executable and arguments are
not part of the command., 204a3e81712000d09a2794cc4ef1d090c4280f4e,9c5242d6a15b14032e9fc1f408be3c91026b1e1f, git-multi-cherry-pick.sh, fatal: ambiguous argument &#39;204a3e81712000d09a2794cc4ef1d090c4280f4e,9c5242d6a15b14032e9fc1f408be3c91026b1e1f&#39;:

I think that is not how we pass the commitIds. Has anyone used the above bash script before?

答案1

得分: 0

我认为你实际上是在寻找 git rebase,而不是 git cherry-pick(这两者都可以执行相同的工作)。在最近的 Git 发布中,git cherry-pick 可以直接处理多个提交,无需外部循环。

<s>
针对你的具体问题:当在命令行上指定多个提交引用时,这些引用需要由你的 shell 的 IFS(输入字段分隔符)分隔,通常是空格,很少是逗号(,)。

可能的解决方案:

  • 将你的映射值更改为 204a3e81712000d09a2794cc4ef1d090c4280f4e 9c5242d6a15b14032e9fc1f408be3c91026b1e1f(注意在脚本中的引号)
  • 在你的脚本中将 IFS 设置为 &#39;,&#39;
    </s>

git cherry-pick 实际上已经可以一次选择多个提交(请参阅文档)。你仍然需要将映射中的值从逗号更改为空格,然后你可以简化你的 shell 脚本。

这也修复了在没有范围的情况下使用 rev-list,而只有 2 个起始点(abc123 def456 而不是 abc123..def456)的问题。它将遍历你的整个历史,而不仅限于两个引用之间的提交。去掉 rev-list,直接使用 cherry-pick

#!/bin/sh

if [ -z "$1" ]; then
    echo "相当于对指定范围内的每个提交运行 git-cherry-pick。";
    echo "";
    echo "用法:$0 start^..end";
    echo "";
    exit 1;
fi


# 不要引用参数,我们需要保留潜在的空格
git cherry-pick $1

(你不需要 bashsh 完全足够用于这样的脚本)

英文:

I think you are actually looking for git rebase, not git cherry-pick (both of which can perform the same work). git cherry-pick in recent Git release can even process multiple commits directly, without the need for an external loop.

<s>
To address your specific question: when specifying several commit refs on the command line, those need to be separated by your shells IFS (input field separator), which is usually whitespace and rarely a comma (,).

Possible solutions:

  • Change your map value to 204a3e81712000d09a2794cc4ef1d090c4280f4e 9c5242d6a15b14032e9fc1f408be3c91026b1e1f (pay attention to quoting in your script)
  • Set IFS in your script to &#39;,&#39;
    </s>

git cherry-pick can already pick multiple commits at once (see documentation). You still need to fix the value in your map from comma to blank, but then you could simplify your shell script.

This also fixes the problem of using rev-list without a range, but only 2 starting points (abc123 def456 instead of abc123..def456). It would traverse all of your history, not only commits between your two refs. Drop the rev-list and utilize cherry-pick directly:

#!/bin/sh

if [ -z &quot;$1&quot; ]; then
    echo &quot;Equivalent to running git-cherry-pick on each of the commits in the range specified.&quot;;
    echo &quot;&quot;;
    echo &quot;Usage: $0 start^..end&quot;;
    echo &quot;&quot;;
    exit 1;
fi


# do not quote parameter, we need potential whitespace preserved
git cherry-pick $1

(and you do not need bash, sh will totally suffice for a script like this)

huangapple
  • 本文由 发表于 2020年4月6日 01:08:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/61046342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定