我有一个家庭作业,我需要对同一个程序进行三种不同的植入。教授建议使用 git 并将每个植入到不同的分支中。问题是,当我对名为 A 的分支进行更改时,它还会修改主分支中的相同文件......我不希望它在每个分支中携带我的更改,而是将更改保存在每个分支上。我该怎么做?
(我是使用 git 的新手) (我们在终端上处理Linux,远程服务器)
编辑:我用来制作项目目录的命令:
git init
git commit -m "my message"
git checkout // to switch branches
git branch branchname // to create a branch
当我这样做时:
$ 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
添加文件并且我不提交而是直接去 bak 到 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
我应该做的是在分支 1 中add
和commit
:
$ 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
我们不会看到修改...不出所料
所以!如果你想在其他分支上工作,即使你还没有完成当前的分支怎么办?
我回到分支 1 并cat
其内容
$ git checkout branch1
Switched to branch 'branch1'
$ cat test.txt
Branch 1
继续编辑
$ echo "Branch 1..1" >> test.txt
让我们add
但不commit
并尝试checkout
掌握
$ 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
时,您可以创建一个新快照,在 Git 中存档所有文件。 每个提交都包含每个文件的完整快照(嗯,它保存的每个文件,但这听起来有点多余,不是吗?这些文件以特殊的、只读的、仅 Git的、压缩的和重复数据删除的形式存储在 Git 中,作为每次提交的一部分。
重复数据消除处理了这样一个事实,即大多数提交大多只是重用以前提交中的现有文件。 如果文件未删除重复,它将使存储库保持比实际小。 但这也意味着实际上不可能使用存储在Git 中的文件。 因此,当您运行git checkout
或git switch
时,Git 将 - 当您从一个提交移动到另一个提交时 -删除旧的签出文件,并从新选择的提交中用新文件替换它们。
为了避免丢失未保存的工作,git checkout
和git switch
都先做一些安全检查。1如果您修改了某个文件,但尚未提交该修改,Git 将尝试将修改后的文件带入新分支。 这并不总是可能的,但是当它确实可行时,您可以准确地看到所看到的:
Switched to branch 'master' M test.txt
这个M
是 Git 的说法:嘿,我注意到你修改了test.txt
。 我不仅销毁了您所做的更改,还能够将分支切换到master
并将文件的修改副本保留在工作树中。 我没有把副本从master
中取出. 如果这不是您要做的,您可能应该切换回另一个分支,添加文件并提交它。
实际上还有很多内容 -包括 Git 何时以及是否可以切换分支 - 当我对当前分支有未提交的更改时,我对 Checkout 另一个分支的回答中有一个更完整的故事。 这是对一个问题的答案,即为什么有时可以,有时不能,在不提交工作的情况下git checkout
另一个分支。 它没有解决git checkout
不如git switch
安全的事实——这个问题本身,以及我的回答,早于新git switch
——也不是关于这是否是一个好主意。 这只是关于底层机制。
现在,请记住,您看到和处理的文件不在 Git 中。 它们在您的工作树中,供您查看和处理,但就 Git 而言,它们只是临时文件,供您使用和Git用git checkout
覆盖。
1安全检查git checkout
可能会被禁用,有时您没有意识到这一点。 这就是为什么git switch
现在存在的原因,以及为什么转换为它是一个好主意,但旧git checkout
仍然有效。 既然你在问题中提到了它,我在这里的例子中主要使用git checkout
。 另外,我已经使用 Git 大约 15 年了,并且从过去糟糕的日子开始就有坏习惯。:-)
你用的是forks
吗?
主分支自动与其他分支同步是很奇怪的。我知道,如果您创建了一个分叉,则可以将其配置为来自源的主分支与分叉中的主分支同步。
基本上,您在另一个分支中的更改不应自动推送到主分支,除非您合并了分支。
你能添加更多细节吗?