【问题标题】:How can I automatically push after committing in Git?在 Git 中提交后如何自动推送?
【发布时间】:2014-02-02 21:17:57
【问题描述】:

如何设置 Git 自动推送到远程 每次提交到本地存储库后存储库(包括自动提供我的密码)?

【问题讨论】:

  • 你推的是什么协议?如果提示输入密码,我假设这是 SSH 或 HTTP。
  • 此外,对于 git 问题,至少提及您正在使用的操作系统总是有帮助的。
  • 我质疑这种设置是否明智。这消除了将您的更改重新组织到不同的提交集(尤其是变基)的任何能力。对于这样的设置,我犯了太多错误,最终对我有用。

标签: git githooks git-push post-commit-hook


【解决方案1】:

首先,确保您可以在不提供密码的情况下手动推送。如果您通过 HTTP 或 HTTPS 推送,则可能是 creating a .netrc file with the login detailsadding your username and password into the URL for the remote。如果你使用 SSH,你可以创建一个私钥没有密码的密钥对,或者use ssh-agent to cache your private key

然后您应该在.git/hooks/post-commit 中创建一个可执行文件 (chmod +x),其中包含以下内容:

#!/bin/sh
git push origin master

...如果您想推送到origin 以外的远程,或者推送master 以外的分支,请自定义该行。确保您使该文件可执行。

【讨论】:

  • 无法让 ssh-agent 记住我的密码,因此必须将其设为空。希望我的妻子不会入侵我的帐户:)
  • 说到定制,如果我想以这种方式推送一些但不是所有分支怎么办?例如,我只想自动推送在.git/config 中注明的具有相应远程分支的分支,前缀为feature/xy/
  • git push --all origin
  • chmod +x .git/hooks/post-commit
  • 如果您不想存储密码,那么这种方法也很有效。只有在每次提交后你必须输入密码。
【解决方案2】:

git-autopush 脚本允许您设置提交后挂钩,类似于“How configure automatic pushing?”中推荐的内容。
但是对于密码,您需要run a ssh-agent

【讨论】:

  • 不需要ssh-agent,只需使用另一个无密码的git-仅ssh-key:ssh-keygen -t ed25519 -f ~/.ssh/id_pushonlyecho $'\nHost pushonly\nHostname DESTINATION\nIdentityFile ~/.ssh/id_pushonly\n' >> ~/.ssh/config。在DESTINATION 上配置git-shell,如superuser.com/a/444899/72223 所示,使用来自~/.ssh/id_pushonly.pub 的公钥。所需的git-URL 类似于git@pushonly:path/to/repo.git。要调试:ssh git@pushonly COMMAND 必须在 DESTINATION 上运行 git-shell -c COMMAND。对于COMMAND,请参阅man git-shell
  • @Tino 谢谢。为什么要使用数字签名方案-t ed25519?我一般使用-t rsa,虽然最近我必须在ssh-keygen 中添加-m PEMstackoverflow.com/a/53645530/6309stackoverflow.com/a/53729009/6309)。
  • @Tino 我知道 rsa 速度较慢,安全性较低(如果它的长度低于 2048 位:bagja.net/blog/upgrade-ssh-key-to-ed25519.html),但我在处理可能无法正确解释 ed255519 签名的较旧的 openssh 服务器.
  • 我主要使用ed25519,因为它为~/.ssh/authorized_keys 提供了简短而方便的行。 what DJB writes about ed255519 也很有趣:针对侧通道(Spectre),更少的 CPU 等安全。顺便说一句,在处理旧的 sshds 时,我通常为它们创建一个特殊的密钥,然后在 ~/.ssh/config 中配置它。
【解决方案3】:

.git/hooks 目录中创建一个名为“post-commit”的文件,内容为“git push”。但如果您想自动提供密码,则需要进行修改。

【讨论】:

  • 什么样的修改?也许扩展答案(和/或指向一些参考或 Stack Overflow 帖子)?
【解决方案4】:

如果您开始使用多个 master 分支,您可能希望自动推送当前分支。我的钩子 (.git/hooks/post-commit) 看起来像这样:

#!/usr/bin/env bash

branch_name=$(git symbolic-ref --short HEAD)
retcode=$?
non_push_suffix="_local"

# Only push if branch_name was found (my be empty if in detached head state)
if [ $retcode -eq 0 ] ; then
    #Only push if branch_name does not end with the non-push suffix
    if [[ $branch_name != *$non_push_suffix ]] ; then
        echo
        echo "**** Pushing current branch $branch_name to origin [i4h post-commit hook]"
        echo
        git push origin $branch_name;
    fi
fi

如果它可以使用 git symbolic-ref 确定分支名称,则推送当前分支。

"How to get current branch name in Git?" 处理获取当前分支名称的这种方式和其他方式。

在您期望会发生sausage making 的任务分支中工作时,每个分支的自动推送可能会令人不安(推送后您将无法轻松地变基)。所以钩子不会推送以定义后缀结尾的分支(在示例中为“_local”)。

【讨论】:

  • 对于第一行,我必须使用#!/bin/sh 才能使其工作。否则它一直说:error: cannot run .git/hooks/post-commit: No such file or directory。谢谢,我最喜欢你的解决方案。
  • 感谢您的评论,@oyalhi,我更新了答案中的 shebang 行。现在应该移植得更好了!
  • 你好我得到这个错误:.git/hooks/post-commit: line 3: unexpected EOF while looking for matching ``' .git/hooks/post-commit: line 17: 语法错误:文件意外结束
  • 嘿,确实有一个丢失的反引号。我更新了答案,请重试
  • 为什么是#!/usr/bin/env bash?它的含义是什么(它应该做什么)?是用 Bash 代替 Dash (sh) 吗?在什么系统上? Ubuntu 16.04 (Xenial Xerus)?为什么和默认的#!/usr/sh不同?
【解决方案5】:

这里是推送/拉取的简单说明,无需通过 SSH 为使用 Linux 和 Windows 的用户提供密码 (Git Bash)

在您的客户端上:

  1. 检查是否生成了 SSH 密钥:

     $ ls ~/.ssh/id_rsa.pub; ls ~/.ssh/id_dsa.pub
     /c/Users/Cermo/.ssh/id_rsa.pub  <-- I have RSA key
     ls: cannot access '/c/Users/Cermo/.ssh/id_dsa.pub': No such file or directory
    
  2. 如果您没有任何密钥(两个“ls: cannot access ...”行),请生成一个新密钥。如果您有任何密钥,请跳过此步骤。

    $ ssh-keygen.exe
    Generating public/private rsa key pair.
    Enter file in which to save the key (/c/Users/Cermo/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase): <-- press Enter
    Enter same passphrase again: <-- press Enter
    
  3. 使用 git 将您的密钥复制到要从中拉取或推送的远程服务器:

    $ ssh-copy-id user_name@server_name
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to
    filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you
    are prompted now it is to install the new keys
    user_name@server_name's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'user_name@server_name'"
    and check to make sure that only the key(s) you wanted were added.
    

注意:在此操作过程中,您必须提供密码。之后,您的拉/推操作将不会请求密码。

注意 2:在使用此过程之前,您必须使用 user_name 至少登录一次服务器(在第一次登录期间创建 SSH 密钥复制到的主目录)。

【讨论】:

    【解决方案6】:

    这是一个让 Git 自动将 push 发送到远程存储库的 Bash 脚本

    1. 自动检查ssh-agent
    2. 使用expect script 自动发送密码
    3. 用法很简单:cd /path/to/your/repository 然后push

    将此脚本添加到文件中,例如$HOME/.ssh/push

    #!/bin/bash
    
    # Check connection
    ssh-add -l &>/dev/null
    [[ "$?" == 2 ]] && eval `ssh-agent` > /dev/null
    
    # Check if Git config is configured
    if [ ! $(git config user.name) ]
    then
        git config --global user.name <user_name>
        git config --global user.email <user_email>
    fi
    
    # Check if expect is installed
    if [[ ! $(dpkg -l | grep expect) ]]
    then
        apt-get update > /dev/null
        apt-get install --assume-yes --no-install-recommends apt-utils expect > /dev/null
    fi
    
    # Check identity
    ssh-add -l &>/dev/null
    [[ "$?" == 1 ]] && expect $HOME/.ssh/agent > /dev/null
    
    # Clean and push the repository
    REMOTE=$(git remote get-url origin)
    URL=git@github.com:${REMOTE##*github.com/}
    [[ $REMOTE == "http"* ]] && git remote set-url origin $URL
    git add . && git commit -m "test automatically push to a remote repo"
    git status && git push origin $(git rev-parse --abbrev-ref HEAD) --force
    
    

    将其链接到/bin 目录,这样就可以通过push 命令调用它:

    sudo ln -s $HOME/.ssh/push /bin/push
    chmod +x /bin/push
    

    【讨论】:

      【解决方案7】:

      如果您使用的是 Husky,它会默认覆盖您的 post-commit 挂钩文件。

      我们在 package.json 中使用这个命令来自动 rebase 并推送任何提交给 master。 (第一次运行yarn add --dev git-branch-is。)

        "husky": {
          "hooks": {
           "post-commit": "git-branch-is master && git rebase origin master && git push origin master"`
          }
        }
      

      【讨论】:

        【解决方案8】:
        1. 创建一个 Git 文件:commit.sh

          #!/bin/sh
          cd c:/Users/Lenovo/Desktop/nalms/src
          git add --all
          timestamp() {
            date +"at %H:%M:%S on %d/%m/%Y"
          }
          git commit -am "Regular auto-commit $(timestamp)"
          git push origin master
          
        2. 打开窗口任务调度器

        3. 创建新任务

        4. 常规 → 为任务命名

        5. 转到触发器部分并启用任务计划程序

        6. 按下完成按钮

        【讨论】:

        • 什么是"window task scheduler"?这是在Windows 上吗?你的意思是Windows Task Scheduler?或者是其他东西?您还可以提供屏幕截图来补充说明(甚至可能是 free-hand circles(不是开玩笑))。请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
        猜你喜欢
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 2013-11-10
        • 2013-09-06
        • 1970-01-01
        • 1970-01-01
        • 2013-12-17
        相关资源
        最近更新 更多