【问题标题】:Is it possible to exclusively make a local copy of a git branch read-only, in order to avoid mistakes? [duplicate]是否可以将 git 分支的本地副本专门设为只读,以避免错误? [复制]
【发布时间】:2018-02-05 11:33:38
【问题描述】:

我正在开发一个我拥有完全权限的 git 存储库。

我想暂时检查一下主分支,以便详细查看一些文件,以了解它们与我的功能分支有何不同。 (git diff 命令非常有用,但目前不适用于我的目的。)

我真的想避免意外写入主分支的可能性。

有没有一种简单的方法可以让我的本地版本的分支暂时只读,而不会为团队中的其他人冻结分支?

【问题讨论】:

  • 如果你真的想确保不修改本地 master,你可以简单地做一个分离的 checkout (git checkout --detach master)。这样,如果您提交某些内容,它就不会出现在任何分支上。但是,除非您推送提交,否则意外提交到本地 master 并不是真正的问题。如果您不小心提交到本地 master,您可以简单地通过git reset --hard origin/master 将本地 master 分支的状态恢复为远程 master 分支的状态(请注意,这将永久丢弃您的工作树/索引中的任何未提交更改)。
  • 值得思考:每一次提交都是只读的。这意味着只要您不remove 提交,向您的存储库添加提交根本不会触及任何现有历史记录。那么:如果你不小心写信给master,你为什么会在意呢?所有的 old 提交仍然存在,就像它们一样。 (参见@Alderath 的评论。)

标签: git github version-control


【解决方案1】:

您可以使用两种方式:

选项1:保护github中的master分支

即使你错误地提交了master 分支,git 也会阻止你将本地 master 分支推送到 github。

保护master 的方式为:在你的 github 仓库中 -> 设置 -> 分支 -> 选择 master -> 合并前需要拉取请求审查 -> 保存更改。 所以不能直接在 master 分支上做修改,应该使用 PR 合并到 master 分支上。

如果您仍然需要以某种方式直接对master分支进行更改,您可以使用选项2。

选项 2:在本地 repo 中使用预提交挂钩

在您的本地存储库中,在 .git/hooks 中,将 pre-commit.sample 重命名为 pre-commit。并在pre-commit 中添加以下脚本:

#!/bin/sh

branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch == "master" ]]
then
 {
   git reset HEAD .
   git checkout -- .
   echo "you tried to commit on master branch, recover master branch and stoppped! "
   exit 1
 }
fi

现在,如果你在 master 分支上错误地提交,git 会将 master 分支重置为原点,并用消息提示你。

注意:命令git reset HEAD .git checkout -- . 将丢弃master 分支上所有未提交的更改。它的基础上的改变是没有用的。如果你想保持master分支上的未提交,你可以忽略这两个命令。

【讨论】:

  • 只输出消息并退出1还不够吗,里面的两个git命令不会丢弃他所有的更改吗?
  • 是的,这两个命令将丢弃主分支上的更改。这只是怀疑不需要将更改应用于功能分支的情况之一。我最初的目的是展示预提交挂钩是如何工作的。但无论如何感谢@LasseV.Karlsen,我会在我的回答中声明。
【解决方案2】:

您可以使用Git hook 来防止这种情况发生

然后制作.git/hooks/pre-commit

#!/bin/sh
if [ $USER != "git-repo-admin" ];
then
  if [ "$1" == refs/heads/master ];
  then
    echo "Pushing to master is restricted"
    exit 1
  fi
fi

如果您自己保留此脚本.git,这不会冻结其他开发人员的分支

【讨论】:

  • lockmaster?不应该是pre-commit 还是从它调用?
  • @phd 你说得对,名字不能随意选择
【解决方案3】:

对此可能有更好的答案,所以我将保留这个问题,但这是我目前最终要做的事情:

git checkout master #BE CAREFUL! JUST COPY IT SOMEWHERE AND GO BACK TO YOUR BRANCH!

mkdir ~/fake-project-master-delete-me-after-september-2017

cp -r ./* ~/fake-project-master-delete-me-after-september-2017

git checkout feature/123456

如果您有一个非常大的存储库,这当然会占用大量驱动器空间。我仍然希望有更好的方法。

====

编辑:当我提出这个问题时,Dylan 和 Marina 发布了他们的答案。在大多数情况下,这些几乎肯定会更好。

【讨论】:

    猜你喜欢
    • 2022-12-12
    • 2020-08-11
    • 2017-08-13
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多