Как выполнить несколько команд git в пакетном файле без завершения после первой команды?
Я попытался поместить серию команд GIT, которые я всегда использую в непрерывном режиме в виде пакетных файлов, чтобы я не повторял слишком много. Например, у меня есть этот командный файл с именем update_repo_branch.bat
для обновления локального репо и синхронизации ветки с удаленной ветвью:
@echo off
if (% 1) ==() goto end
if (% 2) ==() goto end
cd% 1
GIT checkout% 2
git fetch источник
GIT merge oring/% 2
: Конец
Хорошо, чтобы быть ленивым, но я обнаружил, что , когда команда GIT закончена, кажется, что отправляет флаг выхода обратно, чтобы завершить все, что работает. Таким образом, использование пакетного файла для их извлечения всего за один раз просто не работает. Любая идея, как обойти это?
Ответы
Ответ 1
Я не уверен, что это верно для всех пакетов Windows git, но по крайней мере некоторые используют git.cmd
script в качестве обертки вокруг фактических исполняемых файлов git (например, git.exe
). Поэтому, когда вы пакетный файл использует команду git
, Windows фактически запускает другой пакетный файл.
К сожалению, когда один командный файл вызывает другой, по умолчанию он "перескакивает" в вызываемый командный файл, никогда не возвращается (это для совместимости с древними командами MS-DOS или что-то в этом роде).
Вы можете решить эту проблему несколькими способами:
-
вызывать git
в ваших пакетных файлах с помощью команды call
для запуска пакетного файла git.cmd
и возврата обратно к вашим:
call git checkout %2
call git fetch origin
rem etc...
-
вызывать git
в вашем пакетном файле с использованием расширения .exe
явно, чтобы избежать пакетного файла git.cmd
. Для этого вам может потребоваться убедиться, что ваш путь и другие переменные окружения задают способ git.exe
ожидает (это похоже на то, что git.cmd
делает в msysgit):
git.exe checkout %2
rem etc...
Ответ 2
Предполагая, что вы используете msysGit в качестве вашего клиента Git, вы можете использовать сценарии Bash для этого. Вы можете поместить функцию Bash в свой ~/.bashrc
(~ обычно ваш C:\Users\- см. Здесь) следующим образом
update_repo_branch() {
if [ $# != "2" ]; then
echo "Usage: update_repo_branch REPO BRANCH" 1>&2
return 1
fi
cd $1
git checkout $2
git fetch origin
git merge origin/$2
}
Затем вы можете запустить update_repo_branch myrepo cool-branch
из оболочки mysysGit.
Конечно, это не будет доступно из cmd.exe. Вы сможете использовать его только в командной оболочке msysGit cygwin.
Ответ 3
Как я вижу из вашего примера, вы на самом деле пытаетесь синхронизировать локальный ветвь "branchname" с origin/branchname
Для этого вам не нужны никакие дополнительные скрипты, вам просто нужно использовать git pull
вместо последовательности git checkout branchname; git fetch origin; git merge origin/branchname
взгляните на документы о отслеживании ветвей в git и их преимуществах.
вообще говоря, если у вас есть макет репо:
git branch -a
...
master
dev1
dev2
remotes/origin/master
remotes/origin/dev1
remotes/origin/dev2
И ваши ветки dev1 и dev2 отслеживают ветки для origin/dev1 и origin/dev2 соответственно, тогда вам просто нужно выполнить в репозитории:
git pull
Эта команда будет эффективно синхронизировать все локальные ветки отслеживания с удаленными.
Подробнее см. здесь:
Git pull docs
Git удаленные ветки и ветки отслеживания (книга Progit)