Cherry pick отлично работает для нескольких коммитов, но продолжает выдавать сообщение «Вы находитесь в состоянии« отсоединен HEAD »» - PullRequest
0 голосов
/ 08 апреля 2020

Я написал скрипт, который принимает 5 входных данных: 1) URL-адрес клонирования 2) BranchName, с которым необходимо объединить выбор вишни 3) Новое имя ветви, которое необходимо создать со всеми коммитами вишневого выбора 4) cherryPick идентификаторы коммитов. 5) Динамически создаваемый временный каталог, в котором должны выполняться эти операции.

#!/bin/bash

echo 'Start Cherry Pick'

cd $5 || exit

echo 'Switched to '$5
git clone $1 .
git checkout -f origin/$2
git checkout -b $3
git cherry-pick $4
git push origin HEAD
echo '***** SUCCESS *****'

Это хорошо работает и создает новую ветвь на $2 с именем $3 и печатает ***** SUCCESS *****

Start Cherry Pick, Switched to C:\Users\******\Local\Temp\ae85a131-f783-4245-a5df-c4a54f6619b02426345661203195835, 
Cloning into '.'..., Updating files:  29% (359/1216), Updating files:  30% (365/1216)Updating files:  31% (377/1216)Updating files:  32%  (1180/1216)Updating files:  98% (1192/1216)Updating files:  99% (1204/1216)Updating files: 100% (1216/1216)Updating files: 100% (1216/1216), done.

Note: switching to 'origin/master'., 
You are in 'detached HEAD' state. You can look around, make experimental, changes and commit them, and you can discard any commits you make in this, state without impacting any branches by switching back to a branch., If you want to create a new branch to retain commits you create, you may, do so (now or later) by using -c with the switch command. 
Example:,   git switch -c <new-branch-name>, Or undo this operation with:,   git switch -, Turn off this advice by setting config variable advice.detachedHead to false, 
HEAD is now at 9a97592 Merge pull request #25 from gitUserName/CEAS-243, 
Switched to a new branch 'CEAS-1234', 
[CEAS-1234 ca9e831] should be ahead of master AccountManagerTest.cls,  Date: Mon Apr 6 16:35:56 2020 +0530,  1 file changed, 1 insertion(+), 1 deletion(-), 
[CEAS-1234 f7ab9df] should be ahead of master AccountProcessorTest.cls,  Date: Tue Apr 7 00:06:26 2020 +0530,  1 file changed, 1 insertion(+), 1 deletion(-), remote: , 
remote: Create a pull request for 'CEAS-1234' on GitHub by visiting:        , 
remote:      https://github.com/gitUserName/gitRepoName/pull/new/CEAS-1234        , 
remote: , To https://github.com/gitUserName/gitRepoName.git,  * [new branch]      
HEAD -> CEAS-1234, ***** SUCCESS *****]

Но, скажем, в любом сценарии, если скрипт завершится неудачно, например, плохие идентификаторы фиксации, или если создаваемая ветвь уже существует, даже тогда Success is printed и даже то же сообщение, которое это напечатано You are in 'detached HEAD'....

Вот вывод, когда скрипт завершается неудачно:

Start Cherry Pick, 
Switched to C:\Users\NAGESI~1\AppData\Local\Temp\b46aebc4-479a-43f0-a333-cebfad5b9e2a945082863319958458, 
Cloning into '.'..., Updating files:  39% (475/1216), Updating files:  40% (487/1216)Updating files:  41% (499/1216)Updating files:  42% (1168/1216)Updating files:  97% (1180/1216)Updating files:  98% (1192/1216)Updating files:  99% (1204/1216)Updating files: 100% (1216/1216)Updating files: 100% (1216/1216), done.
Note: switching to 'origin/master'., 
You are in 'detached HEAD' state. You can look around, make experimental, changes and commit them, and you can discard any commits you make in this, state without impacting any branches by switching back to a branch., If you want to create a new branch to retain commits you create, you may, do so (now or later) by using -c with the switch command. Example:,   
git switch -c <new-branch-name>, Or undo this operation with:,   git switch -, Turn off this advice by setting config variable advice.detachedHead to false, 
HEAD is now at 9a97592 Merge pull request #25 from gitUserName/CEAS-243, Switched to a new branch 'CEAS-1234', 
[CEAS-1234 f1e152e] should be ahead of master AccountManagerTest.cls,  Date: Mon Apr 6 16:35:56 2020 +0530,  1 file changed, 1 insertion(+), 1 deletion(-), 
[CEAS-1234 03c5681] should be ahead of master AccountProcessorTest.cls,  Date: Tue Apr 7 00:06:26 2020 +0530,  1 file changed, 1 insertion(+), 1 deletion(-), To https://github.com/gitUserName/gitRepoName.git,  ! [rejected]        
HEAD -> CEAS-1234 (non-fast-forward), 
error: failed to push some refs to 'https://github.com/gitUserName/gitRepoName.git', hint: Updates were rejected because the tip of your current branch is behind, hint: its remote counterpart. Integrate the remote changes (e.g., hint: 'git pull ...') before pushing again., hint: See the 'Note about fast-forwards' in 'git push --help' for details., 
***** SUCCESS *****]

Так как мне печатать success только тогда, когда скрипт работает нормально, и печатать сообщение об ошибке и сообщение об ошибке, если что-то не получается. Во-вторых, как избавиться от сообщения You are in 'detached HEAD' state......

Я пытался: $?, но, похоже, он возвращает только код завершения, так что это может быть не очень полезно, в случае ошибки и ошибки сообщение.

Просто к сведению: я запускаю этот скрипт из Java Ant Launcher: где моя цель:

<target name="git_multi_cherry_pick">
    <echo message="START: MultiMerge"/>
    <exec executable="C:\Program Files\Git\bin\bash.exe" osfamily="windows" failonerror="true">
        <arg value="${gitMultiCherryPick}"/>
        <arg value="${gitCloneURL}"/>
        <arg value="${gitBranchName}"/>
        <arg value="${gitNewBranchName}"/>
        <arg value="${cherryPickIds}"/>
        <arg value="${gitDirectory}"/>
    </exec>
    <exec executable="/bin/bash" osfamily="unix" failonerror="true">
        <arg value="${gitMultiCherryPick}"/>
        <arg value="${gitCloneURL}"/>
        <arg value="${gitBranchName}"/>
        <arg value="${gitNewBranchName}"/>
        <arg value="${cherryPickIds}"/>
        <arg value="${gitDirectory}"/>
    </exec>
</target>

И код для запуска этой цели

Map<String, String> propertiesMap = new HashMap<>();
String uuid = String.valueOf(UUID.randomUUID());
Path tempDirectory = Files.createTempDirectory(uuid);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream buildXml = classLoader.getResourceAsStream("build/build.xml");
InputStream gitCherryPick = classLoader.getResourceAsStream("build/git-multi-cherry-pick.sh");
File buildFile = ConsumerHandler.stream2file(buildXml, "build", ".xml");
File cherryPick = ConsumerHandler.stream2file(gitCherryPick, "git-multi-cherry-pick", ".sh");
propertiesMap.put("gitMultiCherryPick", cherryPick.getName());
propertiesMap.put("gitCloneURL", "https://myGitRepo.git");
propertiesMap.put("gitBranchName", "master");
propertiesMap.put("gitNewBranchName", "CEAS-1234");
propertiesMap.put("cherryPickIds", "903f59d668e62e9950cb0616d39defde10a4730c 67faf443bf96e4b51f1d5eb0f93559d8c022e482");
propertiesMap.put("gitDirectory", tempDirectory.toFile().getPath());
List<String> sf_build = AntExecutor.executeAntTask(buildFile.getPath(), "git_multi_cherry_pick", propertiesMap);

И sf_build возвращается с выводом.

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Вы проверяете удаленную ветку (origin/whatever). Git более чем счастлив выполнить, но локальная ветвь в этот момент не создается ... вы остаетесь в detached HEAD состоянии .... и затем вы запускаете свои маги c и делаете git push origin HEAD, и я думаю, что вам не хватает целевой ветви. Это скорее git push origin HEAD:$2? Наконец, не доверяйте выводу std или err, чтобы сказать, прошла ли операция хорошо или нет. Используйте код завершения выполнения, чтобы узнать, все ли в порядке (0 = в порядке. Все, что не в порядке 0 = не в порядке).

0 голосов
/ 08 апреля 2020

Ваш скрипт использует:

git checkout -f origin/$2

сразу после шага git clone. Почему вы использовали это имя для удаленного отслеживания? Вот почему вы находитесь в режиме «отсоединенного HEAD».

Нет ничего неправильного в использовании режима отсоединенного HEAD, и остальная часть вашего сценария обрабатывает его, но если вы не хотите использовать режим отсоединенного HEAD, не запрашивать режим отсоединенного HEAD.

Противоположность режима отсоединенного HEAD - это когда у вас есть подключенный HEAD, т. е. когда вы находитесь в имени ветви. Это можно сделать следующим образом:

  • путем создания нового имени ветви, указывающего на тот же коммит, что и origin/$2, затем
  • переключения на имя этой ветви

, который вы можете сделать за один шаг:

git checkout -B $2 origin/$2

Вы можете удалить -f здесь, так как не должно быть никаких причин использовать -f вообще. Единственная причина использовать здесь B в верхнем регистре в том случае, если $2 - это имя ветки, которое рекомендовал удаленный репозиторий, так что вы уже находитесь в ветке $2, как это. Если удаленный репозиторий рекомендует master и вы никогда не будете использовать master, вы можете вместо этого использовать git checkout -b $2 origin/$2.

Если хотите, вы можете использовать git clone -b $2, чтобы отключить все это, так что Ваша операция клонирования заканчивается эквивалентом git checkout -b $2 origin/$2.

Но, скажем, в любом сценарии, если скрипт завершится неудачно, например, с ошибочными идентификаторами фиксации, или если созданная ветвь уже существует ...

(Как уже отмечалось, ветвь не создается.)

Целесообразно проверять состояние выхода каждой Git команды:

git clone ... || exit
git checkout ... || exit

и так далее. Чтобы сделать эквивалент, без повторяющихся шагов || exit, вы можете установить опцию e:

set -e

перед серией команд, каждая из которых теперь приведет к завершению всего скрипта, как только как любая команда терпит неудачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...