git 是原子推送吗?
Is git push atomic?
多次提交的git push
是原子操作吗?
- 关于同一分支的其他
git push
操作
- 关于来自同一分支的
git pull
操作
对于情况 1。它必须是。否则我的提交会干扰其他人的提交,可能会产生不一致或无效的状态。 Git 通过强迫我首先集成其他人的更改(如果我输掉比赛)或强迫其他人集成我的更改(如果我赢得比赛)来防止这种情况。
但是 2. 呢?如果我的存储库如下所示:
C---D---E master
/
A---B origin/master
有人在做 git pull
而我正在做 git push
会看到 A---B 或 A---B---C---D---E ,或者他们也可以得到介于两者之间的任何东西,例如A---B---C---D?
有效,是的。
请注意,您对其他人使用他们的 存储库所做的事情的控制为零。但是,当您对其他存储库(例如 GitHub 上的存储库)执行 git push
时,真正发生的是:
您的 Git 发送他们 Git 需要的任何提交 and/or 其他对象,以便您的 Git 进行创建或-更新或删除请求。名称只能命名存储在存储库中的一些实际对象,因此如果您要求他们将他们的 master
分支设置为提交 a123456...
,您的 Git 必须首先确保他们 有提交a123456...
.
然后,对于您希望他们更新(或创建或删除)的每个 name,您的 Git 请求(常规推送)或命令(git push --force
和其他设置强制标志的操作)来进行更新。您向他们发送名称 N 和散列 new-hash,作为更新(或创建或删除)请求的列表。每个请求都有一个或有时两个如下所示的哈希值。 (全零散列表示 "delete"。)
你的 Git 可以向他们发送一个礼貌的请求,他们的 Git 将服从,如果它是一个新的分支或标签,或者如果它是一个删除请求,或者如果它是分支名称更新并且更新是快进的。 (除了这些约束之外,控制他们 Git 的任何人都可以设置他们喜欢的任何其他约束,但这些是默认值。)
您的 Git 可以无条件发送命令。默认情况下,他们的 Git 会服从(但和以前一样,无论谁控制他们的 Git 都可以设置额外的约束)。
或者,你的Git可以发送一个命令,但是要有你自己的条件,格式为:我相信你的名字N代表hash ID old-H(对于某些名称和散列,如果您希望它们还没有名称,则旧 H 为全零)。如果他们的名字 N 有散列 old-H,他们的 Git 将服从命令(和以前一样,无论谁控制他们的 Git可以设置额外的约束)。
此更新过程发生在 他们的 Git 在 他们的 存储库中设置的锁下。就您的 Git 而言,此锁使更新成为全有或全无。对于你发送的每个名字,更新要么发生——被接受,现在他们的名字 N 代表 new-hash 你的 Git问/命令-或不要求并被拒绝并且名称未更改。
当你(或任何人)运行 git pull
你真的 运行ning git fetch
然后是第二个纯本地的 Git 命令. git fetch
与 git push
的相似之处在于您的 Git 会调用其他一些 Git,但这次数据传输是相反的:
您的 Git 从他们的 Git 中获取了他们所有姓名和哈希 ID 的列表。如果正在进行推送,则每一对(名称和哈希 ID)来自 before 请求或命令的更新,或者来自 after:没有中间可见,因为他们 Git 尊重他们自己的锁。
然后,使用在此步骤中找到的名称和哈希 ID,您的 Git 根据此列表带来您想要和没有的新对象。
在此过程结束时,您的Git不会触及任何您的分支名称——至少默认情况下不是(你可以用 refspec 参数覆盖它)。相反,您的 Git 会更新您的 远程跟踪名称 ,例如 origin/master
,以匹配他们的名称。 (根据你 运行 git fetch
的方式,你可以限制你的 Git 只更新你的一个或几个名字,而不是全部;如果你只打算更新您的 origin/master
、您的 Git 可以跳过下载只能从他们的 feature-X
访问的新对象,这些对象将成为您的 origin/feature-X
。)
第二个纯本地命令可以执行第二个命令(通常合并,除非您 select rebase)可以执行的任何操作。这部分通常 不是 原子的:例如,在变基过程中,你的变基可能会在中间停止,只复制了一些提交,迫使你修复冲突和 运行 git rebase --continue
。但这都在 您的 存储库中,没有其他人共享。 (您的 Git 也会对您自己的分支名称和其他名称更新执行自己的 lock/unlock 操作,以防您在后台 运行 执行另一个 Git 命令,或通过 cron 作业,或其他任何方式。)
您的 CI 系统通常会有自己的 Git 存储库,它通过从您指定为 its 上游的任何存储库进行复制来更新(例如,一个 Git 集线器)。您的 CI 系统将 运行 git fetch
更新 其 origin/master
。您的 CI 系统如何检查和构建 origin/master
提交取决于它。
多次提交的git push
是原子操作吗?
- 关于同一分支的其他
git push
操作 - 关于来自同一分支的
git pull
操作
对于情况 1。它必须是。否则我的提交会干扰其他人的提交,可能会产生不一致或无效的状态。 Git 通过强迫我首先集成其他人的更改(如果我输掉比赛)或强迫其他人集成我的更改(如果我赢得比赛)来防止这种情况。
但是 2. 呢?如果我的存储库如下所示:
C---D---E master
/
A---B origin/master
有人在做 git pull
而我正在做 git push
会看到 A---B 或 A---B---C---D---E ,或者他们也可以得到介于两者之间的任何东西,例如A---B---C---D?
有效,是的。
请注意,您对其他人使用他们的 存储库所做的事情的控制为零。但是,当您对其他存储库(例如 GitHub 上的存储库)执行 git push
时,真正发生的是:
您的 Git 发送他们 Git 需要的任何提交 and/or 其他对象,以便您的 Git 进行创建或-更新或删除请求。名称只能命名存储在存储库中的一些实际对象,因此如果您要求他们将他们的
master
分支设置为提交a123456...
,您的 Git 必须首先确保他们 有提交a123456...
.然后,对于您希望他们更新(或创建或删除)的每个 name,您的 Git 请求(常规推送)或命令(
git push --force
和其他设置强制标志的操作)来进行更新。您向他们发送名称 N 和散列 new-hash,作为更新(或创建或删除)请求的列表。每个请求都有一个或有时两个如下所示的哈希值。 (全零散列表示 "delete"。)你的 Git 可以向他们发送一个礼貌的请求,他们的 Git 将服从,如果它是一个新的分支或标签,或者如果它是一个删除请求,或者如果它是分支名称更新并且更新是快进的。 (除了这些约束之外,控制他们 Git 的任何人都可以设置他们喜欢的任何其他约束,但这些是默认值。)
您的 Git 可以无条件发送命令。默认情况下,他们的 Git 会服从(但和以前一样,无论谁控制他们的 Git 都可以设置额外的约束)。
或者,你的Git可以发送一个命令,但是要有你自己的条件,格式为:我相信你的名字N代表hash ID old-H(对于某些名称和散列,如果您希望它们还没有名称,则旧 H 为全零)。如果他们的名字 N 有散列 old-H,他们的 Git 将服从命令(和以前一样,无论谁控制他们的 Git可以设置额外的约束)。
此更新过程发生在 他们的 Git 在 他们的 存储库中设置的锁下。就您的 Git 而言,此锁使更新成为全有或全无。对于你发送的每个名字,更新要么发生——被接受,现在他们的名字 N 代表 new-hash 你的 Git问/命令-或不要求并被拒绝并且名称未更改。
当你(或任何人)运行 git pull
你真的 运行ning git fetch
然后是第二个纯本地的 Git 命令. git fetch
与 git push
的相似之处在于您的 Git 会调用其他一些 Git,但这次数据传输是相反的:
您的 Git 从他们的 Git 中获取了他们所有姓名和哈希 ID 的列表。如果正在进行推送,则每一对(名称和哈希 ID)来自 before 请求或命令的更新,或者来自 after:没有中间可见,因为他们 Git 尊重他们自己的锁。
然后,使用在此步骤中找到的名称和哈希 ID,您的 Git 根据此列表带来您想要和没有的新对象。
在此过程结束时,您的Git不会触及任何您的分支名称——至少默认情况下不是(你可以用 refspec 参数覆盖它)。相反,您的 Git 会更新您的 远程跟踪名称 ,例如
origin/master
,以匹配他们的名称。 (根据你 运行git fetch
的方式,你可以限制你的 Git 只更新你的一个或几个名字,而不是全部;如果你只打算更新您的origin/master
、您的 Git 可以跳过下载只能从他们的feature-X
访问的新对象,这些对象将成为您的origin/feature-X
。)
第二个纯本地命令可以执行第二个命令(通常合并,除非您 select rebase)可以执行的任何操作。这部分通常 不是 原子的:例如,在变基过程中,你的变基可能会在中间停止,只复制了一些提交,迫使你修复冲突和 运行 git rebase --continue
。但这都在 您的 存储库中,没有其他人共享。 (您的 Git 也会对您自己的分支名称和其他名称更新执行自己的 lock/unlock 操作,以防您在后台 运行 执行另一个 Git 命令,或通过 cron 作业,或其他任何方式。)
您的 CI 系统通常会有自己的 Git 存储库,它通过从您指定为 its 上游的任何存储库进行复制来更新(例如,一个 Git 集线器)。您的 CI 系统将 运行 git fetch
更新 其 origin/master
。您的 CI 系统如何检查和构建 origin/master
提交取决于它。