如何不将对文件所做的更改从一个分支转移到另一个 git

How do I not transfer changes done to files from a branch to a another in git

我有一个家庭作业,我需要对同一个程序进行三种不同的植入。教授建议使用 git 并在不同的分支中进行每次植入。事情是,当我在一个名为 A 的分支上进行更改时,它也会修改主分支中的同一个文件......我不希望它在每个分支上进行我的更改,而是将更改保存在本地每个分支单独。我该怎么做?

(我刚开始使用 git) (我们在 linux,一个远程服务器上工作,在终端上)

编辑:我用来创建项目目录的命令:

git init

git commit -m "my message"

git checkout // to switch branches

git branch branchname // to create a branch

您在使用 forks 吗?

奇怪的是master分支自动同步到other分支。我知道,如果你已经创建了一个 fork,那么它可以被配置为来自 origin 的 master 分支与你的 fork 中的 master 分支同步。

基本上,你在其他分支上的更改不会自动推送到 master 分支,除非你合并了你的分支。

你能补充更多细节吗?

当我这样做时:

$ git init
Initialized empty Git repository in MyPath/Test1/.git/

然后我创建一个文件test.txt

$ touch test.txt
$ git add test.txt
$ git commit -m " commit 1 "

现在想在不同的分支修改

$ git checkout -b branch1
$ echo "Branch 1" >> test.txt

这是棘手的部分... 如果我 使用 git add test.txt 添加文件并且我 提交但直接返回 master:

$ git checkout master
Switched to branch 'master'
M       test.txt

我会在master看到修改!!:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt

我应该做的是addcommitin branch1:

$ git checkout branch1
$ git add test.txt
$ git commit -m "commit from branch 1"
[branch1 1b562f5] commit from branch 1
 1 file changed, 1 insertion(+)
$ git log
commit 1b562f5be40a50df04f8a2a15b58a7af61742275 (HEAD -> branch1)
Author: xxxxxx<xxxxx.xxxx.xxx@xxxx.com>
Date:   Thu Jun 3 16:36:30 2021 +0200

    commit from branch 1

commit 03684e2a02c1a37a8f4546f296c6802686c7a4e9 (master)
Author: xxxx<xxx.xx.xx@xxxx.com>
Date:   Thu Jun 3 16:31:05 2021 +0200

     commit 1

如果我返回 master 并检查日志:

$ git checkout master
Switched to branch 'master'

$ git log
commit 03684e2a02c1a37a8f4546f296c6802686c7a4e9 (HEAD -> master)
Author: xxxxx<xxxxx.xxxx.xxxxx@xxxx.com>
Date:   Thu Jun 3 16:31:05 2021 +0200

     commit 1

我们不会看到修改...如预期的那样

太棒了!如果你想在其他分支上工作,即使你还没有完成当前分支怎么办?

我回到 branch1 和cat它的内容

$ git checkout branch1
Switched to branch 'branch1'
$ cat test.txt
Branch 1

继续编辑

$ echo "Branch 1..1" >> test.txt

add 而不是 commit 并尝试 checkoutmaster

$ git add test.txt
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        test.txt
Please commit your changes or stash them before you switch branches.
Aborting

不可能!你必须 commit 之前,但是!您不希望每次更改分支时都进行新提交,因此您可以 commit --amend

$ git commit --amend
$ git log
commit 40a3a66e2b45a253f9a6ed564e977887c0748bf0 (HEAD -> branch1)
Author: xxxxx<xxxxx.xxxxx.xxxxx@xxxxx.com>
Date:   Thu Jun 3 16:36:30 2021 +0200

    commit from branch 1 => I can edit the comment!!

commit 03684e2a02c1a37a8f4546f296c6802686c7a4e9 (master)
Author: xxxxx<xxxxx.xxxxx.xxxxx@xxxxx.com>
Date:   Thu Jun 3 16:31:05 2021 +0200

     commit 1

现在我可以安全地git checkout master

您在工作树中看到和编辑的文件(普通文件)实际上并不在 Git 中。当您 运行 git checkout (或新的 git switch 时,它们被 Git 中复制出来;两者都为这个特殊目的;git switch 被添加到 Git 2.23 中作为一种更安全的结帐方式)。

当您 运行 git add 然后 git commit 时,您制作了 new 快照,将所有文件存档在 Git.每个提交都包含每个文件的 完整快照 (好吧,它包含的每个文件,但这听起来有点多余,不是吗?)。 这些 文件存储在 Git 中,以特殊的、只读的、Git-only、压缩和 去重 形式,作为每次提交的一部分。

重复数据删除处理了这样一个事实,即大多数提交大多只是重复使用以前提交的现有文件。如果不对文件进行重复数据删除,它会使存储库适当地变小。但这也意味着 使用 存储在 Git 中的文件实际上是不可能的。因此,当您 运行 git checkoutgit switch 时,Git 将——当您从一个提交移动到另一个提交时——删除 旧的检查out 文件并用新选择的提交中的新文件替换它们

为了避免丢失未保存的工作git checkoutgit switch都先做一些安全检查。1 如果你已经修改了一些文件,但还没有提交那个修改,Git会尝试把那个修改过的文件带走, 进入新的 b运行ch。这并不总是可能的,但是当它发生时,您会看到您所看到的:

Switched to branch 'master'
M       test.txt

这个M是Git的说法:嘿,我注意到你修改了test.txt。我不仅可以破坏您所做的更改,还可以将 b运行ches 切换为 master 将文件的修改副本 保留在您的工作树中。我没有从 master 中取出副本。如果这不是您想要的,您应该切换回另一个 b运行ch,添加文件并提交它。

实际上还有更多内容——包括 Git 何时以及是否可以完全切换 b运行ches——更完整的故事在我对 [=34= 的回答中].这是对一个问题的回答,为什么你有时可以,有时不能,git checkout 另一个 b运行ch 而不是提交你的工作。它没有解决 git checkout 不如 git switch 安全的事实——问题本身,以及我的回答,早于 新的 git switch——并且与这是否是一个好主意无关。只是关于底层机制.

现在,请记住 您查看和处理的文件不在 Git 中。它们在您的工作树中,供您查看和处理,但就 Git 而言,它们只是临时文件,供您使用和使用Git 用 git checkout 覆盖。


1git checkout 中的安全检查可以被禁用,有时您没有意识到。这就是 git switch 现在存在的原因,也是转换为它的好主意,但旧的 git checkout 仍然有效的原因。既然你在你的问题中提到了它,我在这里的例子中主要使用 git checkout 。另外,我已经使用 Git 大约 15 年了,并且从过去的糟糕日子里养成了坏习惯。 :-)