git:如何向一个远程分支而不是另一个分支添加和提交更改?

git:如何向一个远程分支而不是另一个分支添加和提交更改?,git,github,version-control,Git,Github,Version Control,因此,我知道推送到特定遥控器的方法是: git推送主机其中主机是我的本地分支 我在本地做了一些敏感的更改,我想推送到远程A,但不是远程B。但要推送到远程A,我需要在本地分支上添加并提交更改,然后才能推送。然而,在我这样做之后,提交不会出现在我的本地分支历史记录中吗?我是否必须在将来推送到远程B之前手动删除该提交,或者是否有更成熟的方法来执行此操作?(因为每次我在远程A上工作时,我都必须记住再次进行更改,反之亦然)这部分取决于您对Git的信任程度,因为在过去糟糕的日子里(Git 1.5或1.6左右

因此,我知道推送到特定遥控器的方法是:

git推送主机
其中主机是我的本地分支


我在本地做了一些敏感的更改,我想推送到远程A,但不是远程B。但要推送到远程A,我需要在本地分支上添加并提交更改,然后才能推送。然而,在我这样做之后,提交不会出现在我的本地分支历史记录中吗?我是否必须在将来推送到远程B之前手动删除该提交,或者是否有更成熟的方法来执行此操作?(因为每次我在远程A上工作时,我都必须记住再次进行更改,反之亦然)

这部分取决于您对Git的信任程度,因为在过去糟糕的日子里(Git 1.5或1.6左右),我看到Git将不应该发送的对象发送到远程。所以我,至少,不会这么信任,但这就是它应该如何工作的

我们需要一些定义,否则我们会被Git中一些不太好的命名绊倒。它们在下面(接近末尾),因此如果您已经熟悉它们,可以跳过它们

底线是,当您执行
推送
时,您的git将向远程发送您的分支提示提交,以及从该点(即,它的所有祖先)到远程已有的任何提交都可以访问的所有提交。它还将包括这些提交所需的所有文件。它应该只发送这些提交和文件,也就是说,如果某些敏感文件或数据不在这些提交中,并且远程设备还没有这些文件或数据,则推送后远程设备不应该拥有这些文件或数据

最终,这可能意味着您应该为两个远程设备保留两组不同的分支。或者更好-首先不要将任何敏感数据放入Git。将其保存在存储库之外的某个位置。如果需要可能包含此类数据的配置文件,请在存储库中包含一个敏感的无数据示例配置,并使用
.gitignore
避免将真实配置放入存储库

讨论 请记住,分支名称“指向”特定提交(通过包含其ID):

该提交指向它们的父提交(通过包含它们的ID),也指向指向blob的树,这些blob为您获取与这些提交相关的文件。为了处理提交,Git需要一些起点,比如这个SHA-1散列
3ad15fd…
。它将从那里向后工作,遵循所有这些指针,以便检查任何特定的提交。每个ID(提交、树或文件的)都给Git底层对象的“真实名称”,Git使用这个真实名称来提取实际内容

因此,如果某个文件中有敏感数据,Git存储它的方式是在某个blob ID下。通过Git查看它的方式是使用提交ID启动Git,Git使用提交ID查找树和blob ID。Git然后使用树指定的名称提取blob对象,这样您就有了一个具有正确名称和敏感数据内容的文件

如果Git根本没有blob对象,那么很明显,您无法从Git中获得它。如果它有blob对象,但没有提交点(通过树),则无法按文件名获取它,但可以通过一些维护命令让Git显示每个blob的原始ID,并按ID提取它们,从而找到该数据。(通常比这更容易,只要
git fsck--lost-found

这意味着要确保敏感数据不在某个Git存储库中,必须确保blob本身不在其中。这也意味着任何引用blob的提交都不能存在,因为Git不允许您有一个包含“丢失”blob的提交。(这样的存储库被认为是坏的:您在尝试使用它时会出现错误,尽管Git会尽其所能让您恢复任何您可以恢复的数据。)

git-push
语法和语义 git push的语法被简化为我们这里只关心的语法:

git推送远程refspec

运行此操作时,git首先根据其
url
设置连接到命名的
remote
(实际上,如果设置了它的
pushurl
,如果没有设置,则返回到
url
)。远程主机(通常是一些遥远的主机,如github)运行一个命令,通常是
git receive pack
,然后从您自己的
git push
读取请求

您的
git推送
首先发送提交对象的ID,实际上是将这些对象提供给远程运行的
receive pack
。远程用户会回答“我已经有了”或“好的,我会把它发给我。”Git的工作就是只提供完成推送所需的对象。Git应该首先提供通过解析您提供的refspec的
src
部分找到的提交ID,然后提供完成该提交所需的树和blob,以及该提交的祖先,直到远程设备显示“我已经有了那个”。这就是Git如何知道要发送什么,并且只能发送远程设备上尚未发送的内容。1

然后,Git打包这些对象并发送包。这应该只包含提供和接受的对象。根据Git已经拥有的声明,可以针对Git知道Git拥有的对象进一步压缩这些内容

(在过去糟糕的日子里,这就是事情似乎无法按预期运行的地方,因为我的发送机器会将不必要的、事实上无法访问的对象发送到远程。这是不应该发生的。我不确定这是在提供/接受阶段还是在包构建阶段的失败,还是由其他非正统的stuf造成的f我当时正在做什么。)

最后,你的Git se
$ git rev-parse master
3ad15fd5e17bbb73fb1161ff4e9c3ed254d5b243
git push remote1 mybranch:theirbranch
git push remote2 differentbranch:theirbranch
git push remote3 3ad15fd:refs/heads/branch
[remote "origin"]
    url = git://some.host.somewhere.com/path/to/repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*