Git 如何避免来自本地分支的意外数据提交

Git 如何避免来自本地分支的意外数据提交,git,git-svn,git-branch,dcommit,Git,Git Svn,Git Branch,Dcommit,有时,我在git中创建本地分支,当我尝试从它们提交数据时,我希望得到一条警告消息 如何防止自己意外地从本地分支提交数据?首先想到的是使用git预提交钩子来解决问题。这对于纯吉特回购来说很容易: 锁定远程分支(更新挂钩): 锁定本地分支(预提交挂钩): 但正如中所讨论的,这并不完全有效。提出了一个(被接受的)方案,他利用了一个中间的裸回购协议,就像git和SVN之间的代理一样 也许这对你也有帮助 如果您使用的是Linux(或Git bash或Cygwin或类似版本),那么预提交钩子的另一种替代

有时,我在git中创建本地分支,当我尝试从它们提交数据时,我希望得到一条警告消息


如何防止自己意外地从本地分支提交数据?

首先想到的是使用git预提交钩子来解决问题。这对于纯吉特回购来说很容易:

  • 锁定远程分支(更新挂钩):
  • 锁定本地分支(预提交挂钩):
但正如中所讨论的,这并不完全有效。提出了一个(被接受的)方案,他利用了一个中间的裸回购协议,就像git和SVN之间的代理一样


也许这对你也有帮助

如果您使用的是Linux(或Git bash或Cygwin或类似版本),那么预提交钩子的另一种替代方法是将
Git
包装到shell助手函数中。将以下内容添加到您的
~/.bashrc
(对于bash、Git-bash)或
~/.zshrc
(对于zsh)文件中,或添加任何与shell等效的内容:

real_git=$(which git)
function git {
    if [[ ($1 == svn) && ($2 == dcommit) ]]
    then
        curr_branch=$($real_git branch | sed -n 's/\* //p')
        if [[ ($curr_branch != master) && ($curr_branch != '(no branch)') ]]
        then
            echo "Committing from $curr_branch; are you sure? [y/N]"
            read resp
            if [[ ($resp != y) && ($resp != Y) ]]
            then
                return 2
            fi
        fi
    fi
    $real_git "$@"
}
(我用红帽上的bash和zsh以及Cygwin上的bash对此进行了测试)

无论何时调用
git
,现在都将调用此函数,而不是普通的二进制文件。该函数将正常运行git,除非您在连接到非主分支时调用了
git svn dcommit
。在这种情况下,它将提示您在执行提交之前进行确认。您可以通过显式地指定
git
的路径来覆盖该函数(这就是
$real\u git
所做的)

请记住,在更新
~/.bashrc
或同等版本后,您需要通过启动新的shell会话(注销并再次登录)或运行
source~/.bashrc
来重新加载它


编辑:作为一项增强功能,您可以删除第一行,从
real\u git=
开始,并用
命令git
替换
$real\u git
的其他实例,这实现了相同的功能,但采用了首选的方式。我没有更新脚本本身,因为我无法在zsh上测试更改。

如果其他人需要Windows Powershell:

    function CallGit
    { 
        if (($args[0] -eq "svn") -And ($args[1] -eq "dcommit")) {
            $curr_branch = &{git branch};
            $curr_branch = [regex]::Match($curr_branch, '\* (\w*)').captures.groups[1].value
            if ($curr_branch -ne "master") {
                Write-Warning "Committing from branch $curr_branch";
                $choice = ""
                while ($choice -notmatch "[y|n]"){
                    $choice = read-host "Do you want to continue? (Y/N)"
                }
                if ($choice -ne "y"){
                    return
                }
            }
        }
        &"git.exe" @args
    }
    Set-Alias -Name git -Value CallGit -Description "Avoid an accidental git svn dcommit on a local branch"

不是内置的,而是一个想法:分支后,立即执行
git配置——将“svn remote.svn”部分重命名为“no svn remote”
。一旦您想要执行dcommit,您可以将其还原。或者我可以以某种方式指定此本地分支没有上游分支?你知道我怎么做吗?我根据你的问题研究了一下,但是看起来git svn没有本地分支开关,所以它认为它仍然在主干或签出分支/标记上。为了测试这一点,可以尝试更改配置文件中的默认分支行+1顺便说一句,如果您想测试它是如何工作的,
git svn dcommit--dry run
将触发与
git svn dcommit
相同的检查行为,而不实际尝试执行提交本身。我使用的是linux+zsh,您的解决方案对我来说应该不会太难适应,当我可以的时候我会尝试。我刚刚在zsh中测试了上面的内容;这对我来说很好。只需将代码放入
~/.zshrc