Сделать оболочку script для обновления 3 git repos
Я работаю с 5 репозиториями, которые я клонировал в своей среде разработки.
Когда я хочу обновить репозиторий git, я вхожу в папку/home/adrian/repo1/и делаю:
git мастер проверки
git основной источник тяги
Но потом, каждое утро я должен делать то же самое для других 4 репозиториев. Это довольно хлопотно.
Можно ли поместить это в оболочку script? Я имею в виду, если я напишу эти команды git в оболочке script и запустим его, смогу ли я обновить все репозитории?
Я подумывал написать что-то вроде этого...
cd repo1
git checkout master
git pull origin master
cd ..
cd repo2
git checkout master
git pull origin master
cd ..
(я на Linux)
Изменить: Может быть, это более сложно, чем я думал. В большинстве случаев, когда я делаю "git pull origin master", я получаю erorrs как "Ваши локальные изменения... будут перезаписаны слиянием". Так что я должен войти в соответствующую ветку и засунуть вещи..
Изменить 2:
То, что я собираюсь сделать, - это конфликт, проигнорируйте его и перейдите к следующему репо
cd repo1
git checkout master
git pull origin master
(if there is conflict, ignore and go to the next line but dont stop here)
cd ..
cd repo2
git checkout master
git pull origin master
cd ..
но я не знаю, как записать это в скобках.
Ответы
Ответ 1
Во-первых, я рекомендую не использовать git pull
. Вместо этого создайте более безопасный псевдоним git up
:
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
См. этот ответ для объяснения git up
.
Затем вы можете безопасно script it:
#!/bin/sh
for repo in repo1 repo2 repo3 repo4; do
(cd "${repo}" && git checkout master && git up)
done
Ответ 2
Поскольку у меня много git repo проверено локально для работы, я решил написать более подробный script для обновления всего репо (bash script будет искать git repos до 3 папок глубокое обновление. Затем он выполнит git stash, fetch, rebase и stash, чтобы вернуть локальные изменения. script для меня работает в оболочке git bash на окнах.
#!/bin/bash
# Usage:
# ./update_git_repos.sh [parent_directory]
# example usage:
# ./update_git_repos.sh C:/GitProjects/ [MAKE SURE YOU USE / SLASHES]
updateRepo() {
local dir="$1"
local original_dir="$2"
cd $dir # switch to the git repo
repo_url=$(git config --get remote.origin.url)
echo "****************************************************************************"
echo "Updating Repo: $dir with url: $repo_url"
echo "Starting update in $PWD"
main_branch="master"
if [ "$repo_url" == "[email protected]:repo/repo.git" ]; then # if you have a repo where the primary branch isnt master
$main_branch="trunk"
fi
# update the repo, then stash any local changes
echo -e "\ncalling: git fetch --all && git stash"
(git fetch --all && git stash)
current_branch=$(git rev-parse --abbrev-ref HEAD)
# switch to master/trunk branch and rebase it, then switch back to original branch
if [ $current_branch != $main_branch ]; then
echo -e "\ncalling: git checkout $main_branch && git rebase && git checkout $current_branch"
(git checkout $main_branch && git rebase && git checkout $current_branch)
fi
# rebase the original branch and then stash pop back to original state
echo -e "\ncalling: git rebase && git stash pop on branch: $current_branch"
(git rebase && git stash pop )
#switch back to the starting directory
cd $original_dir
echo ""
}
directory_to_update=${1}
if [ -z "$directory_to_update" ] ; then
echo "no directory passed in, using current directory"
directory_to_update=$PWD
fi
echo "Updating git repo in directory: $directory_to_update"
count=0
for dir in $(find $directory_to_update -maxdepth 4 -type d -name .git | xargs -n 1 dirname); do
updateRepo $dir $directory_to_update #& #uncomment to make it run in multiple threads, meh
((count+=1))
done
echo "$count local git repos have been updated!"
Ответ 3
Я знаю, что я действительно опоздал на вечеринку по этому вопросу, но вот небольшой сценарий оболочки, который я написал для этой конкретной цели.
Это, вероятно, кажется очень любительским, но это потому, что это, вероятно, так! В основном я написал это, чтобы помочь себе освоить bash, но я надеюсь, что это поможет вам (или тому, кто сейчас читает это).
В этом есть много ненужного мусора, который вы можете удалить (например, изменить цвет текста и перечислить репозитории с незафиксированными изменениями), который вы можете удалить.
Ссылка на репо здесь
#!/bin/bash
declare -a my_array
for f in *; do
if [ -d "$f" ] ; then
cd "$f"
echo -e "\n ------------------ NEW REPOSITORY ------------------\n"
echo "Now checking $f"
if [ -d .git ] ; then
git add .
git diff-index --quiet HEAD --
if [ "$?" -ne 0 ] ; then
echo "THE REPO NEEDS TO BE COMMITTED"
my_array=( "${my_array[@]}" "${PWD##*/}" )
fi
git status
git push
git pull
fi
cd ..
fi
done
RED='tput setaf 1'
reset='tput sgr0'
green='tput setaf 2'
if [ ${#my_array[@]} -ne 0 ]; then
var=$(IFS=' '; echo "${my_array[*]}")
var="${RED}$var${reset}"
if [ ${#my_array[@]} -eq 1 ]; then
var="The repository $var"
var="$var has uncomitted changes."
else
var="The repositories $var"
var="$var have uncomitted changes."
fi
echo "$var"
Ответ 4
Я бы предложил управлять обновлением всех репозиториев с помощью скрипта cron.
Вот пример сценария для автоматического обновления базы до их апстрима.
#!/bin/bash
repo_update() {
echo -e "\nUpdating $1" && cd $1
if [[ 'git rev-parse --abbrev-ref HEAD' != master ]]; then git checkout master; fi
GIT_URL=$(git config --get remote.origin.url) && REMOTE=${GIT_URL##*:}
REMOTE=https://api.github.com/repos/${REMOTE%.*}
UPSTREAM=$(curl -s $REMOTE | jq -r '.parent.ssh_url')
if [[ $UPSTREAM == null ]]; then return 1; fi
if grep -q $UPSTREAM << EOF
'git remote -v'
EOF
then
git remote set-url upstream $UPSTREAM
else
git remote add upstream $UPSTREAM
fi
git fetch --prune upstream
if [[ 'git rev-list HEAD...upstream/master --count' == 0 ]]
then
echo -e "all the same, do nothing"
else
echo -e "update exist, let checking!"
git pull --rebase upstream master
git reset --hard upstream/master
push $GIT_URL
fi
}
# Check connection
ssh-add -l &>/dev/null
if [[ "$?" == 2 ]]; then eval 'ssh-agent' > /dev/null; fi
# Check identity
ssh-add -l &>/dev/null
if [[ "$?" == 1 ]]; then expect $HOME/.ssh/agent > /dev/null && ssh-add -l; fi
# Update repositories
find ~/.gits -maxdepth 1 -mindepth 1 -type d | while read repo; do repo_update $repo; done