制作一个shell脚本来更新3 git repos

ado*_*ado 23 git shell

我正在使用我在开发环境中克隆的5个回购.当我想更新git仓库时,我输入文件夹/ home/adrian/repo1 /并执行:

git checkout master git pull origin master

但是,每天早上我必须为其他4个回购做同样的事情.这很麻烦.

我可以把它放在shell脚本中吗?我的意思是,如果我在shell脚本中编写这些git命令并运行它,我能否更新所有的repos?

我在想写这样的东西......

cd repo1
git checkout master 
git pull origin master
cd ..
cd repo2
git checkout master 
git pull origin master
cd ..
Run Code Online (Sandbox Code Playgroud)

(我在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 ..
Run Code Online (Sandbox Code Playgroud)

但我不知道如何在括号中写出这个东西.

Ric*_*sen 27

首先,我建议不要使用git pull.相反,创建一个更安全的git up别名:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
Run Code Online (Sandbox Code Playgroud)

请参阅此答案以获得解释git up.

Then you can safely script it:

#!/bin/sh
for repo in repo1 repo2 repo3 repo4; do
    (cd "${repo}" && git checkout master && git up)
done
Run Code Online (Sandbox Code Playgroud)

  • @adriancdperu:这取决于您的喜好/情况。如果要更新当前签出的分支,则不;如果你只想更新`master`,那么是的。(我有一个更高级版本的简单 `git up` 别名,我用它一次更新我的所有分支。因此,我不需要 `git checkout` 任何东西。) (2认同)

小智 5

由于我有很多git repo在本地签出工作,因此我决定编写一个更详细的脚本来更新所有repo(bash脚本将搜索git repos最多3个文件夹进行更新。然后它将执行git stash,fetch ,rebase和stash弹出本地更改,对我来说,脚本在Windows上的git bash shell中运行。

#!/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!"
Run Code Online (Sandbox Code Playgroud)