bash-通过bash为多个git存储库切换git协议

bash-通过bash为多个git存储库切换git协议,git,bash,shell,sed,Git,Bash,Shell,Sed,在linux上,有一些git repo,其.git/config包含以下3行: [remote "origin"] url = git@github-eo:eric/workspace.git # url = https://eric@github.com/eric/workspace.git [远程“源”] url=git@github-eo:eric/workspace.git #url=https://eric@github.com/eric/workspace.git (

在linux上,有一些git repo,其
.git/config
包含以下3行:

[remote "origin"] url = git@github-eo:eric/workspace.git # url = https://eric@github.com/eric/workspace.git [远程“源”] url=git@github-eo:eric/workspace.git #url=https://eric@github.com/eric/workspace.git (提示:最后两行以制表符开头。)

问题是:

#!/bin/bash

# repo array,
repo_arr=(
    "/mnt/star/git_repository/workspace" 
    "/media/ERIC/node"
    "/mnt/star/workplace/eclipse_j2ee_workplace/eric"
)

protocol="null"

url_prefix_comment=""
url_prefix_uncomment=""

repo_count=0

# read protocol,
if [ $# -ge 1 ]; then
    protocol=$1
fi

# check protocol,
if [ $protocol == "ssh" ]; then
    url_prefix_comment="https"
    url_prefix_uncomment="git"
elif [ $protocol == "https" ]; then
    url_prefix_comment="git"
    url_prefix_uncomment="https"
else
    echo "invalid protocol: $protocol"
    exit 1;
fi


# switch protocol for repo in array,
for i in "${!repo_arr[@]}"; do 
    if [ -d "${repo_arr[$i]}" ]; then
        sed -i "s/^\turl = $url_prefix_comment/\t# url = $url_prefix_comment/g" "${repo_arr[$i]}/.git/config"
        sed -i "s/^\t# url = $url_prefix_uncomment/\turl = $url_prefix_uncomment/g" "${repo_arr[$i]}/.git/config"

        repo_count=$(expr $repo_count + 1)
    else
        echo "non exists repo: ${repo_arr[$i]}"
    fi
done

echo "Done, switch to protocol [$protocol], repo count: {$repo_count}."

exit 0
  • 我想通过bash将
    #
    从第三行移动到第二行,可能是通过sed,还可以将其移回。我的意思是触发这两行,如何在bash中调用sed

@更新: 通过参数选择协议以编写脚本:

#!/bin/bash

# repo array,
repo_arr=(
    "/mnt/star/git_repository/workspace" 
    "/media/ERIC/node"
    "/mnt/star/workplace/eclipse_j2ee_workplace/eric"
)

protocol="null"

url_prefix_comment=""
url_prefix_uncomment=""

repo_count=0

# read protocol,
if [ $# -ge 1 ]; then
    protocol=$1
fi

# check protocol,
if [ $protocol == "ssh" ]; then
    url_prefix_comment="https"
    url_prefix_uncomment="git"
elif [ $protocol == "https" ]; then
    url_prefix_comment="git"
    url_prefix_uncomment="https"
else
    echo "invalid protocol: $protocol"
    exit 1;
fi


# switch protocol for repo in array,
for i in "${!repo_arr[@]}"; do 
    if [ -d "${repo_arr[$i]}" ]; then
        sed -i "s/^\turl = $url_prefix_comment/\t# url = $url_prefix_comment/g" "${repo_arr[$i]}/.git/config"
        sed -i "s/^\t# url = $url_prefix_uncomment/\turl = $url_prefix_uncomment/g" "${repo_arr[$i]}/.git/config"

        repo_count=$(expr $repo_count + 1)
    else
        echo "non exists repo: ${repo_arr[$i]}"
    fi
done

echo "Done, switch to protocol [$protocol], repo count: {$repo_count}."

exit 0
实际上,我将为脚本提供一个参数,它应该是
ssh
https
,该参数将决定取消注释哪一行,以及注释哪一行,如果两个协议之一的行不存在,则忽略它

顺便说一下,我只需要sed部分来修改这两行,我可以编写bash的其他部分,以节省您的时间

我想这样做的原因:

#!/bin/bash

# repo array,
repo_arr=(
    "/mnt/star/git_repository/workspace" 
    "/media/ERIC/node"
    "/mnt/star/workplace/eclipse_j2ee_workplace/eric"
)

protocol="null"

url_prefix_comment=""
url_prefix_uncomment=""

repo_count=0

# read protocol,
if [ $# -ge 1 ]; then
    protocol=$1
fi

# check protocol,
if [ $protocol == "ssh" ]; then
    url_prefix_comment="https"
    url_prefix_uncomment="git"
elif [ $protocol == "https" ]; then
    url_prefix_comment="git"
    url_prefix_uncomment="https"
else
    echo "invalid protocol: $protocol"
    exit 1;
fi


# switch protocol for repo in array,
for i in "${!repo_arr[@]}"; do 
    if [ -d "${repo_arr[$i]}" ]; then
        sed -i "s/^\turl = $url_prefix_comment/\t# url = $url_prefix_comment/g" "${repo_arr[$i]}/.git/config"
        sed -i "s/^\t# url = $url_prefix_uncomment/\turl = $url_prefix_uncomment/g" "${repo_arr[$i]}/.git/config"

        repo_count=$(expr $repo_count + 1)
    else
        echo "non exists repo: ${repo_arr[$i]}"
    fi
done

echo "Done, switch to protocol [$protocol], repo count: {$repo_count}."

exit 0
我想这样做,因为有时由于网络或github错误,
ssh
无法工作,我不知道,当时我需要将所有git repo从
ssh
切换到
https
,但是当
ssh
工作正常时,我会使用它,因为我不需要每次输入密码

我还问过为什么ssh有时不工作,但没有解决这个问题,所以我必须编写一个脚本,用一个命令来帮助触发它


总结: 感谢您的回答和评论,我将把解决方案总结如下

解决方案:

#!/bin/bash

# repo array,
repo_arr=(
    "/mnt/star/git_repository/workspace" 
    "/media/ERIC/node"
    "/mnt/star/workplace/eclipse_j2ee_workplace/eric"
)

protocol="null"

url_prefix_comment=""
url_prefix_uncomment=""

repo_count=0

# read protocol,
if [ $# -ge 1 ]; then
    protocol=$1
fi

# check protocol,
if [ $protocol == "ssh" ]; then
    url_prefix_comment="https"
    url_prefix_uncomment="git"
elif [ $protocol == "https" ]; then
    url_prefix_comment="git"
    url_prefix_uncomment="https"
else
    echo "invalid protocol: $protocol"
    exit 1;
fi


# switch protocol for repo in array,
for i in "${!repo_arr[@]}"; do 
    if [ -d "${repo_arr[$i]}" ]; then
        sed -i "s/^\turl = $url_prefix_comment/\t# url = $url_prefix_comment/g" "${repo_arr[$i]}/.git/config"
        sed -i "s/^\t# url = $url_prefix_uncomment/\turl = $url_prefix_uncomment/g" "${repo_arr[$i]}/.git/config"

        repo_count=$(expr $repo_count + 1)
    else
        echo "non exists repo: ${repo_arr[$i]}"
    fi
done

echo "Done, switch to protocol [$protocol], repo count: {$repo_count}."

exit 0
  • 使用
    bash
    sed
    ,查看Eric Wang(我)的答案。它适用于linux,我想mac可能需要对
    选项卡进行一些修改,以匹配,windows可能无法使用它
  • 使用
    bash
    awk
    ,参见
    anubhava
    的答案
  • 定义多个远程,1个用于ssh,1个用于https,然后通过选择远程来选择协议,请参见William Pursell的问题注释。我想这将适用于所有系统
  • 对另一个指定协议行的文件使用
    [包括]
    ,并在需要时更改软链接,可以编写shell脚本来帮助切换软链接,而不是更改文件内容,请参见
    gniourf\u gniourf
    的问题注释。我想这至少适用于类unix系统

    • awk
      可能是更好的选择:

      awk -v kw='(https|ssh):' 'p ~ /^\turl/ && $0 ~ kw && $0 ~ /^\t#[[:blank:]]*url/ {
         sub(/^\t/, "\t# ", p)
         sub(/^\t*#[[:blank:]]*/, "\t")
      }
      p!="" {
         print p
      }
      {
         p=$0
      }
      END {
         print p
      }' file
      
      [remote "origin"]
          # url = git@github-eo:eric/workspace.git
          url = https://eric@github.com/eric/workspace.git
      

      我刚刚通过
      sed
      了解了如何做到这一点,下面是脚本:


      代码 git\u协议\u交换机。sh:

      #!/bin/bash
      
      # repo array,
      repo_arr=(
          "/mnt/star/git_repository/workspace" 
          "/media/ERIC/node"
          "/mnt/star/workplace/eclipse_j2ee_workplace/eric"
      )
      
      protocol="null"
      
      url_prefix_comment=""
      url_prefix_uncomment=""
      
      repo_count=0
      
      # read protocol,
      if [ $# -ge 1 ]; then
          protocol=$1
      fi
      
      # check protocol,
      if [ $protocol == "ssh" ]; then
          url_prefix_comment="https"
          url_prefix_uncomment="git"
      elif [ $protocol == "https" ]; then
          url_prefix_comment="git"
          url_prefix_uncomment="https"
      else
          echo "invalid protocol: $protocol"
          exit 1;
      fi
      
      
      # switch protocol for repo in array,
      for i in "${!repo_arr[@]}"; do 
          if [ -d "${repo_arr[$i]}" ]; then
              sed -i "s/^\turl = $url_prefix_comment/\t# url = $url_prefix_comment/g" "${repo_arr[$i]}/.git/config"
              sed -i "s/^\t# url = $url_prefix_uncomment/\turl = $url_prefix_uncomment/g" "${repo_arr[$i]}/.git/config"
      
              repo_count=$(expr $repo_count + 1)
          else
              echo "non exists repo: ${repo_arr[$i]}"
          fi
      done
      
      echo "Done, switch to protocol [$protocol], repo count: {$repo_count}."
      
      exit 0
      

      叫它
      它能做什么 它将有助于为bash数组中列出的所有repo切换协议。 当然,需要手动为每个回购协议添加2行2协议


      干杯:}

      什么是输入文件只有一行,即
      \turl=git@github-eo:ericoudesu/linux_workspace.git
      ?还需要评论吗?@anubhava我更新了问题,请看。也许,你只是想介绍另一个遥控器?我的意思是,一个远程设备专用于只读
      https://
      ,另一个远程设备专用于r/w
      ssh://
      ?@user3159253我更新了问题,解释了我为什么需要脚本,请参考。您是否尝试过编写
      sed
      命令来完成您想要的任务?我测试过,似乎未注释的行在选项卡后面有一个空格,你能帮我把它去掉吗?非常感谢,我认为这是一个解决办法。但我刚刚在sed中找到了如何做到这一点,请参阅我的另一个答案。