開発環境でクローンを作成した5つのリポジトリで作業しています。 gitリポジトリを更新する場合、フォルダー/ home/adrian/repo1 /を入力して、次の操作を行います。
git checkout master git pull Origin master
しかし、その後、毎朝、他の4つのレポについても同じことをしなければなりません。これは非常に面倒です。
これをシェルスクリプトに入れることはできますか?つまり、これらのgitコマンドをシェルスクリプトで記述して実行すると、すべてのリポジトリを更新できますか?
私はこのようなものを書くことを考えていました...
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」を実行すると、「...へのローカル変更はマージによって上書きされます」などのエラーが発生します。だから私はそれぞれのブランチに入り、ものを隠さなければなりません。
編集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 ..
しかし、私は括弧内に物を書く方法を知りません。
最初に、I git pull
の使用を推奨しません 。代わりに、より安全なgit up
エイリアスを作成します。
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
git up
の説明については、 この回答 を参照してください。
その後、安全にスクリプトを作成できます。
#!/bin/sh
for repo in repo1 repo2 repo3 repo4; do
(cd "${repo}" && git checkout master && git up)
done
多くのgitレポジトリをローカルでチェックアウトしているため、すべてのレポジトリを更新するためのより詳細なスクリプトを作成することにしました(bashスクリプトは、更新するために最大3つのフォルダまでgitレポジトリを検索します。 、リベース、およびstashを実行すると、ローカルの変更が元に戻ります。
#!/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" == "git@someserver: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's 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!"
私はこの質問でパーティーに本当に遅れていることを知っていますが、この正確な目的のために書いた小さなシェルスクリプトを次に示します。
おそらく非常に素人っぽいようですが、それはおそらくそうだからです!私は主に自分がbashを学ぶのを助けるためにこれを書きましたが、それがあなた(または今これを読んでいる人)に役立つことを願っています。
削除できる(テキストの色の変更、コミットされていない変更のあるリポジトリの一覧表示など)削除できる不要な綿毛がたくさんあります。
リポジトリへのリンクは here です
#!/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"
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's 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