使用 GIT 部署代码 - 签出与重置 -- 难吗?

2024-01-29

我需要确保服务器上的 python 部署位置之一始终与远程分支同步,并删除服务器上的任何更改。选项 1 和选项 2 有什么区别?哪一个是首选?我打算及时运行它,以确保服务器代码与远程同步。

选项1:

git clean -f -x
git fetch --all
git reset --hard origin/master

选项2:

git clean -f -x
git fetch --all
git checkout --force origin/master

为了正确理解差异,让我们从这些定义开始:

  • Git 存储库包含commits,它们是目录中一些文件树的快照(tree)以及关联的元数据,通常包括一个父提交(但允许任意数量的父提交 ID)。这些提交由丑陋的大哈希 ID 来标识,deadc0defeedbeefac0ffee...等等。因为这些丑陋的大哈希 ID 又大又丑,而且看起来是随机的,所以我们使用名称(主要是分支名称和标签名称)来跟踪它们。

    存储在存储库中的文件具有仅对 Git 本身有用的形式。普通命令无法读取它们。 (除了 Git 之外没有什么可以write这些存储的对象,并且它们具有一次写入的形式:一旦写入,它们就永远不能更改。所有四种 Git 对象都是如此,但是not分支名称,它们是supposed更改:每次向分支添加新提交时,存储在分支名称下的哈希 ID 都会更改。)

  • 每个存储库还有一个index。索引(请注意,有一个特殊的、显着的“the”索引)是您构建next您打算做出的承诺。它开始匹配一些现有的提交。索引有多种作用,包括让 Git 运行得更快(它的cache角色),并处理合并并安排下一次提交(其暂存区角色)。但它开始匹配一些现有的提交。

    索引本质上是一棵扁平树,因此它就像以特定方式提交的内容。与内部 Git 对象一样,它的形式仅对 Git 有用。

  • 大多数存储库还有一个(单一的、可区分的)工作树,这是您处理文件的地方。与索引一样,树开始时匹配某些提交。不过,由于这些是计算机其余部分可以处理的普通文件,因此可以写入和读取它们,或者您可以添加新文件或删除文件。

    如果更改工作树中的文件并想要提交新版本,则必须将该文件从工作树复制到索引中。这是什么git add作用:它将一个文件复制到索引中,要么替换现有文件(如果文件的路径名之前在该索引中),要么存储一个全新的文件(如果路径名是新的)。

    同样,要从索引中删除文件,您必须运行git rm。默认情况下,这将从中删除文件both索引and工作树(但您可以告诉它保留工作树版本)。

  • A repository always1 has one current commit. This is called the HEAD commit. The way .git/HEAD (it's an ordinary file, in the .git directory) really works is that it normally just contains the current branch name. The actual commit ID is stored under the branch name. However, Git has what is called "detached HEAD" mode, where HEAD contains a hash ID instead. This all matters in a moment for both git checkout and git reset.

所以,有一个当前提交,通常来自当前分支名称,加上分支名称实际上只是查找名称到 ID 映射以查找提交的一种方式。我们称之为HEAD,它是:“嘿,Git,去阅读.git/HEAD,查找当前分支名称,并使用它来查找当前提交。或者,如果我处于分离 HEAD 模式,请阅读.git/HEAD和以前一样,但是看到它有一个哈希 ID,然后that'是当前提交。”

现在,您在这里看到的两个不同的命令是git reset and git checkout。这些都有很大不同goals:

  • git reset is (mostly2) about changing the current branch name's name-to-ID mapping in some way, with the option of also changing the index too, or even changing all three: the current commit, the index, and the work-tree.

  • git checkout(主要)是关于改变当前分支是哪个分支,通过将新的分支名称写入 HEAD,或通过“分离”HEAD:将提交哈希 ID 写入 HEAD。正在进行中,git checkout will更改索引和工作树。

这就是事情变得有点复杂的地方。 :-) 既然你正在使用--hard, git reset will更新索引和工作树。所以现在听起来更像是git checkout,在某些方面确实如此。但有几个关键的区别:

  1. Using git reset 提交当前分支指向的更改。 Using git checkout变化哪个提交是当前的。

    请记住,我们上面说过,像这样的名字master and develop是我们如何让 Git 记住又大又难看的哈希 ID。其效果是这些名称就像标签一样,粘贴到或指向特定的提交。这git reset命令让你move标签:改变它指向的位置;将其从一个特定的提交上剥离并将其粘贴到另一个提交上。相比之下,git checkout does not移动标签。相反,它改变了哪个分行名称存储在.git/HEAD. You git checkout master切换到分支master, 进而git checkout develop切换到分支develop。标签保持在原来的位置,但 Git 改变了name存储在.git/HEAD.

    所有这些都适用于normal情况,当你“在树枝上”时。如果你处于“分离的 HEAD”情况,git reset仍然将你分离的 HEAD 从一个提交移动到另一个提交 - 但因为没有分支name涉及,这不会更改任何现有的分支名称。同样,如果你git checkout不是分支名称的东西,git checkout通过将原始提交 ID 写入“分离你的 HEAD”.git/HEAD.

    注意git reset永远不会分离 HEAD,也永远不会重新连接 HEAD。那就是git checkout做。同时,git checkout从不更改任何分支标签,但是git reset does.

  2. The git checkout命令尝试非破坏性(无论如何,在这种模式下;再次参见脚注 2)。这git reset命令愉快地销毁未保存的工作.

    实际上,这意味着如果您对索引和/或工作树进行了更改,git checkout不会覆盖它们。这变得特别复杂,因为它will如果可以的话,切换分支或提交。它通过将未保存的工作保留在索引和/或工作树中(如果可以的话)来实现这一点。如果不能,它就会出错。

    相比之下,git reset --hard将丢弃这些未保存的更改:--hard意味着覆盖索引和工作树。

在评论中,您添加了:

我想忽略任何人可能在服务器上所做的任何提交(尽管这不太可能)

但“忽略”与“丢弃”不同,并且这些都不能解决对索引和/或工作树所做的未提交的更改。

通常,使用这样的集中式服务器的正确做法是设置一个没有工作树,即,是一个--bare存储库。没有工作树的存储库不能在其中完成任何工作。首先没有什么可以保留、可以忽略或可以丢弃的东西。如果您使用这种方法,所有这些区别都会消失。这是你最好的选择。

即使您不能或不会使用--bare存储库,让我们看看剩余的项目。除了上述所有考虑因素之外,请记住,集中式存储库是某人可以访问的存储库git pushes new首先提交——仍然有一个当前(HEAD)提交,如果它没有分离——命名一个当前分支。它仍然有一个索引,如果不是空的,还有一个工作树。 Git 通常会拒绝推送到工作树的当前分支:请参阅receive.denyCurrentBranch in the git config文档 https://www.kernel.org/pub/software/scm/git/docs/git-config.html。由于裸存储库没有工作树,因此对于裸存储库来说,这个特定的 Git 问题也消失了。

(不过,您的描述听起来好像您没有将其设置为其他人直接推送到的中央服务器,而是作为另一台服务器的客户端,您在其中使用git fetch在客户端上。如果是这样的话,下面的几项就不再是问题了。)

因此,假设您有一个带有工作树的非裸存储库。为了让推送成功,您可能需要使用分离的 HEAD,否则 Git 将拒绝推送到当前分支。 (较新的 Git 有能力接受它们,但您必须非常小心地使用它;有关详细信息,请参阅链接的文档。)分离的 HEAD 将为您提供没有当前分支的当前提交,并且将使git reset and git checkout比在树枝上更亲近的表兄弟。

(它还破坏了客户端在克隆中央存储库时看到的一个功能:客户端将检查服务器上当前的哪个分支,即客户端询问服务器“你的 HEAD 分支是什么?”并自动检查出来。此功能有一些可疑的价值,所以你可能不会错过它,但值得注意。)

如果您使用这个分离的 HEAD,那么,之间的主要区别git reset --hard origin/master and git checkout origin/master是未提交的索引和/或工作树修改发生的情况。和git reset --hard,他们将在没有警告的情况下被消灭。任何在服务器上积极工作的人都将SOL http://www.urbandictionary.com/define.php?term=SOL。索引和工作树将被重新设置以匹配新的提交。

如果你是not使用分离的 HEAD,git reset --hard origin/master将写入提交 IDorigin/master到当前分支名称。像之前一样,git reset也会更新索引和工作树。这不仅消除了积极的工作,而且扔掉通过从旧提交上剥离分支标签并将其粘贴到新提交上,在当前分支上进行提交。

With git checkout, well, this is also a bit complicated. Since origin/master is a so-called remote-tracking branch, checking out this name gives you a detached HEAD, with the commit hash stored directly in .git/HEAD. This is true regardless of whether HEAD was attached or detached before. So HEAD now is detached, provided that the checkout succeeds. If there are no uncommitted changes in the index and work-tree, the checkout should3 succeed. If there are uncommitted changes, the checkout will carry them to the new detached HEAD if possible, or fail if switching to that commit cannot be done without wiping out the uncommitted work.

因此,如果您选择沿着这条道路前进,这些就是您的选择。由于 Git 是一个大型工具集,而不是一个单一的固定解决方案,因此您可以选择一些other路径(如果更合适)。

(注意git clean -f -x将删除未跟踪和忽略的文件,即不在索引中的文件。没有-d但是,它不会删除未跟踪的目录。)


1There is an exception to this "always a current commit" rule, used mainly for the case of a new, empty repository, when there are no commits at all. You won't encounter this exception unless you are working in an empty repository, or use git checkout --orphan to create a new but unborn branch, as Git calls it.

2Both git reset and git checkout have additional usages that deviate, anywhere from a little bit to a lot, from their main function. I am describing only their main function here.

3A git checkout can still fail due to, e.g., running out of disk space.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 GIT 部署代码 - 签出与重置 -- 难吗? 的相关文章

  • 解决方案具有位于解决方案文件夹外部的项目

    我尝试通过选择将我的解决方案添加到本地存储库File 添加到源代码管理 但我收到以下消息 源代码控制 Git当前解决方案包含位于解决方案文件夹外部的项目 这些项目不会在 Git 存储库中进行源代码控制 要将所有项目添加到单个 Git 存储库
  • 当 git 说它正在“解决增量”时,它在做什么?

    在存储库的第一次克隆期间 git 首先接收对象 然后花费大约相同的时间 解析增量 在克隆的这个阶段实际上发生了什么 的阶段git clone are 接收存储库数据库中所有对象的 pack 文件 为收到的包创建索引文件 查看头部修订版 显然
  • Git 命令以编程方式将文件的一系列行添加到索引?

    我想要一个命令可以让我做类似的事情 git manual add some file txt 10 20 这相当于 git add p some file txt 并说y仅包含第 10 行到第 20 行的大块 是否有内部 git 命令可以让
  • 全局 Git 忽略

    我想将 Git 设置为全局忽略某些文件 我添加了一个 gitignore文件到我的主目录 Users me 并且我添加了以下行 tmproj 但它并没有忽略这种类型的文件 知道我做错了什么吗 您需要设置您的全局core excludesfi
  • libgit2如何获取当前目录的状态?

    如何获取单个目录而不是整个存储库的状态 我查看了以下内容 git status list new它获取存储库状态 但我只关心位于单个目录中的文件 git status file获得单身状态 有没有办法可以使用 libgit2 获取单个目录的
  • 如何比较本地 Git 分支与其远程分支

    我怎样才能看到diff本地分支和远程分支之间 git diff
  • 从 master 分支部署特定功能

    假设我们使用两个分支进行开发 staging and master 在迭代期间 所有团队成员所做的所有更改都会定期合并到staging分支并出现在我们的暂存环境中 客户能够查看更改并提供反馈 在迭代结束时我们合并staging分支到mast
  • Git merge --squash 可以保留提交注释吗?

    有没有一种方法可以自动添加压缩后的所有提交注释mybranch执行时提交 git merge squash mybranch 这样单个提交包含所有提交注释的串联mybranch 我认为这就是 git merge squash 自动执行的操作
  • VS Code / Bitbucket / SSH - 权限被拒绝(公钥)

    我试图通过 ssh 从 vscode 访问 bitbucket 但总是得到权限被拒绝 公钥 SSH 密钥位于 ssh 公钥已正确设置在bitbucket settings security sshkeys 按键已经过测试并且可以工作 启动后
  • 我应该从哪里安装 git:xcode-select --install 还是brew install git?

    我应该从哪里安装 git xcode select install or brew install git 你需要做xcode select install无论如何 如果你想做任何开发 然后你可以做 brew install git 它将安
  • 是否可以在不从 git 克隆或拉取的情况下获取分支名称?

    我想获取 git 存储库的所有分支名称 目前 我克隆存储库 然后将它们获取到本地计算机上 这是低效的 因为我所需要的只是名称而不是其他 我想知道是否可以这样做 如果是这样 我可以使用什么命令 在本地 无需克隆 您可以键入 使用 gitls
  • Emacs shell:保存提交消息

    我几天前开始使用 emacs 在 emacs shell M x shell 中使用 git 时遇到问题 当我 git commit 或 git commit amend 时 它会打开 vim 来编辑并保存提交消息 我对此表示同意 但我找不
  • 空提交的 Git 补丁

    我创建一个空提交 git commit allow empty m something important 有时它很有用 例如协调 2 个 或更多 不同的 git 树 然而 当我 git format patch 空提交被省略 因为它们不与
  • git:推送单个提交

    假设我进行了多次提交 并希望挑选哪些提交到远程存储库 我该怎么做 在ascii中 C1 gt C2 gt C3 gt C4 我想推C2和C4 通过变基 重置 推送然后重置进行重新排序是否有效 C1 gt C2 gt C3 gt C4 gt
  • Git 和外部备份。子目录是空的,我宁愿它不是空的。

    我想使用 Git 创建外部备份系统 这部分是受到答案的启发在外部磁盘上备份整个 git 存储库的最佳方法是什么 https stackoverflow com a 4372855 2533127 其中建议如下 您还可以通过启动一个新的存储库
  • 更快的“git rebase --preserve-merges”方法

    我通过创建一系列功能分支来使用 git 并在完成后将它们合并到 mastergit merge no ff 这会创建空的合并提交 可用于识别先前功能分支的起点和终点 为了处理多个并发分支 甚至嵌套分支 我使用 rebase 我从不合并回去
  • 使用可通过 FTP 访问的 Web 服务器进行 Git 托管?

    我运行一个 糟糕的 网站 托管在第三方网络服务器上 我可以通过 FTP 访问我的 Web 服务器 据推测 Git 本身具有通过 FTP 推送 拉取的能力 由于我的 Web 服务器已经可以随处访问 我希望将其用作集中式 Git 存储库 我可以
  • 如何防止自动工具自动重新生成配置脚本?

    有时由于SCM没有严格记住文件的时间戳 生成的Makefile会认为需要重新运行 autoreconf i 或相当于从Makefile am重新生成Makefile in 从configure ac重新生成配置等 我该如何防止这种情况 我想
  • 使用 git 同时维护不同版本的代码

    我有一个需要优化的代码 我想同时维护一组版本的代码 每个版本可以描述为一些功能 优化的组合 最终 我将决定哪个版本是最好的 我不想将这些版本合并为更少的版本 但是 我希望能够对 大 源文件进行 小 修改 这可能会跨版本转移 并且我希望这一修
  • 运行 npm install - 如何配置不使用 SSH(端口被防火墙阻止)

    当我跑步时npm install大多数模块配置正确 然而 至少有人想击中ssh 拉取模块的地址 不幸的是 我的公司有一项政策 不允许内部网络之外的 SSH 连接 我收到的具体错误是 Error while executing npm ERR

随机推荐

  • 当我指定凭据时,为什么我的 Http 客户端会发出 2 个请求?

    我创建了 RESTful Web 服务 WCF 在其中检查每个请求的凭据 我的一个客户是 Android 应用程序 服务器端的一切似乎都很棒 我收到请求 如果它有正确的标头 我会处理它 等等 现在我创建了使用此服务的客户端应用程序 这就是我
  • java jprogressbar 在繁重操作期间挂起

    我正在编写一个 java 程序 在调用大量使用 CPU 的方法之前 我会显示一个带有 JProgressBar 的框架 虽然我在调用方法之前显示它 但直到方法结束才显示 JProgressBar 进度条 还 没有以任何方式与该方法交互 这就
  • 如何将汉字一一拆分?

    如果没有特殊字符 如空白 等 在名字和姓氏之间 那么下面如何拆分汉字呢 use strict use warnings use Data Dumper my fh DATA my fname 小三 my lname 张 while my n
  • 监控浏览器控制台中的所有 JavaScript 事件

    是否可以监听所有的javascript事件 我试图猜测 AJAX 请求修改 DOM 后是否会触发事件 With firebug http getfirebug com wiki index php Command Line API moni
  • Git 恢复未按预期工作

    我遇到了问题git revert命令 我使用 Ubuntu 12 04 Linux 和 Git 版本 1 7 9 5 我创建了一个全新的b test repo在我的本地电脑上 从远程跟踪它origin b test repo 我在本地创建了
  • 在 C# 中创建部分(或有界)FileStream

    我有一个 FileStream 它由放入一个文件中的多个文件组成 并且我有一个文件长度的列表 换句话说 我可以轻松计算所有文件的位置和长度 我想要创建的是一个 Open 方法 它接受文件索引并返回仅包含该文件的流 目前我已经使用内存流实现了
  • 如何从maven pom文件构建项目

    我有一个开源项目的 Maven pom 文件 这个pom文件包含所有信息 比如它所依赖的其他jar等 我安装了maven 创建一个 samprj 目录并将 pom 文件复制到该目录中 cd 进入该目录并运行 mvn 命令而不带任何参数 但我
  • 什么是 git 边界提交

    The git log command https git scm com docs git log has a boundary选项 这会导致程序 输出排除的边界提交 但什么是边界提交 我什么时候可以将它们包含在输出中 边界提交是限制修订
  • 为什么我们需要 onUpgrade(); SQLiteOpenHelper 类中的方法

    我正在关注这个教程 http www androidhive info 2011 11 android sqlite database tutorial http www androidhive info 2011 11 android s
  • Excel 宏第一次工作,然后下次就很慢

    因此 在未共享的工作表中运行我的宏时 它工作得很好 没有任何问题 只要我共享它 通常第一次就会运行良好 但第二次需要永远运行 如果我第一次运行宏后关闭工作簿并重新打开它将再次运行良好 我尝试清除剪贴板 还尝试了使用宏清除剪贴板的另一个版本
  • dax 中选取不同值的动态总和

    以下是样本数据 Week Practice Type capacity Gen 1 BI c 80 0 1 BI c 80 1 1 BI sc 160 1 1 BI pc 240 0 1 BI pc 240 3 1 BI mc 1160 1
  • 如何在 pandas 中填充直到一天结束?

    我有一个pandas TimeSeries与日内指数 如何分别填充 前向填充 每天的 NaN 值 以这个系列为例 2013 03 27 22 07 00 04 00 1 0 2013 03 27 22 08 00 04 00 nan 201
  • 当我们从 Fragment 类调用 facebook 或 twitter 时如何处理后退按钮?

    我想从 Fragment 连接 Facebook 和 Twitter 但是当我从 Facebook 或 Twitter 返回时 应用程序已关闭 我想留在该应用程序中 我的代码在这里 Override public View onCreate
  • Java:将光标保持在某个区域

    对于玩过 Madness Interactive 的人来说 最令人沮丧的事情之一就是当光标离开游戏区域时 您不小心点击了 这会导致游戏失焦 你的角色会在几秒钟内死亡 为了解决这个问题 我想制作一个可以在后台运行的java应用程序 它将光标保
  • Tkinter 在 Windows XP 上激活窗口

    我有一个小型 GUI 应用程序 用于侦听网络消息 以便用户可以更新一些信息并接受它 这是在生产工厂环境中 用于与特定的物理硬件交互 在某些情况下通过串行 工作流程如下所示 用户正在与另一个程序交互 5250 绿屏 他们输入特定的键绑定 将
  • 来自位图源的图像的 LazyColumn 闪烁/闪烁

    我是 Jetpack Compose 的新手 我目前正在开发一个聊天应用程序 我要求用户从图库中选择图像或从相机中拍照 然后我将文件 Uri 保存到数据库中 然后监听所有消息的列表 当此列表更新时 此图像正在重新组合并闪烁 视图模型中的消息
  • 我的 PHP 脚本缓存(公共)友好吗?

    我已经完成了一个可以提供许多文档的小型 PHP 应用程序 这些文件must可由客户端缓存and代理 由于代理可以缓存我的结果 因此我必须格外小心 因为我提供的文档可以具有不同的 MIME 类型 基于 SERVER HTTP ACCEPT 的
  • arm-none-eabi 和 arm-linux-gnueabi 之间的区别?

    arm none eabi 和 arm linux gnueabi 有什么区别 我知道如何使用它们的区别 一种用于裸机软件 另一种用于在 Linux 上运行的软件 但技术背景是什么 我发现 ABI 存在差异 据我所知 它类似于 API 但在
  • Jquery mousedown 与 click

    今天我发现了一些让我很困惑的事情 我只是试图通过 jquery 隐藏 s th 首先我尝试使用这个 specificdiv li nth child 3 click function anotherdiv hide 但它不起作用 一段时间后
  • 使用 GIT 部署代码 - 签出与重置 -- 难吗?

    我需要确保服务器上的 python 部署位置之一始终与远程分支同步 并删除服务器上的任何更改 选项 1 和选项 2 有什么区别 哪一个是首选 我打算及时运行它 以确保服务器代码与远程同步 选项1 git clean f x git fetc