当前位置: 首页 > 知识库问答 >
问题:

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

公良理
2023-03-14

我正在使用我在开发环境中克隆的5个repo。当我想更新git repo时,我输入文件夹/home/adrian/repo1/并执行以下操作:

git签出主git拉起源主

但是,每天早上我都要为其他4个回购做同样的事情。这是相当麻烦的。

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

我在考虑写这样的东西。。。

cd repo1
git checkout master 
git pull origin master
cd ..
cd repo2
git checkout master 
git pull origin master
cd ..

(我在linux上)

编辑:也许这比我想象的更具挑战性。大多数时候,当我做"git拉源主",我得到错误,如"您的本地更改......将被合并覆盖。"所以我必须进入各自的分支机构,把东西藏起来...

编辑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 ..

但是我不知道如何在括号里写这个东西。

共有3个答案

诸葛彦
2023-03-14

我知道我在这个问题上真的迟到了,但这里有一个我为这个目的写的小脚本。

它可能看起来很业余,但那是因为它可能是!我写这篇文章主要是为了帮助自己学习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"
何甫
2023-03-14

由于我有很多git repos在本地检查工作,我决定写一个更详细的脚本来更新所有的repos(bash脚本将搜索git repos到3个文件夹深更新。然后,它将执行git隐藏、读取、重新设置和隐藏本地更改。我的脚本运行在git bash shell在Windows上。

#!/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!"
韩琛
2023-03-14

首先,我建议不要使用git拉。相反,创建一个更安全的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
 类似资料:
  • 第一个shell脚本 编写 打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用php好了。 输入一些代码,第一行一般是这样: #!/bin/bash #!/usr/bin/php “#!”是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行。 运行 运行Shell脚本有两种方法: 作为可执行程序

  • 问题内容: 我想知道是否有可能告诉bash 分别对stdout / stderr的所有调用或随后的后续调用? 一种快速而又肮脏的解决方案是编写自己的printf实现,并使用它代替内置的任何实现,但是在我看来,我可能不需要这样做。 我正在编写同时运行的多个构建脚本,出于调试的需要,我 确实 需要查看它们按顺序编写的消息。 问题答案: 如果命令使用stdio并连接到终端,则会按行刷新它们。否则,您需要

  • 终于到shell 脚本这章了,在以前笔者卖了好多关子说shell脚本怎么怎么重要,确实shell脚本在linux系统管理员的运维工作中非常非常重要。下面笔者就带你正式进入shell脚本的世界吧。 到现在为止,你明白什么是shell脚本吗?如果明白最好了,不明白也没有关系,相信随着学习的深入你就会越来越了解到底什么是shell脚本。首先它是一个脚本,并不能作为正式的编程语言。因为是跑在linux的s

  • bash csh ksh zsh 基本语法 定义和使用变量 #!/bin/sh a=" hello world" echo $a echo 'a is xiaxaiwen${a}' if else if ....; then   .... elif ....; then   .... else   .... fi [] 条件测试 [] 中前后一定要加空格 sh

  • 本文向大家介绍详解Shell脚本中调用另一个Shell脚本的三种方式,包括了详解Shell脚本中调用另一个Shell脚本的三种方式的使用技巧和注意事项,需要的朋友参考一下 主要以下有几种方式: Command Explanation fork 新开一个子 Shell 执行,子 Shell 可以从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回给父 Shell。 exec 在同

  • 问题内容: 我已经成功运行了几个Python脚本,并使用subprocess模块​​从基本脚本中调用了它们: 但是,每个脚本都执行一些模拟(来自C ++应用程序的.exe文件),这些模拟会生成一些输出到外壳程序。所有这些输出都从启动这些脚本的位置写入基本shell。我想为每个脚本生成一个新的shell。我试图在调用subprocess.call时使用该属性生成新的shell (也尝试过popen)