16

我显然根本不懂 git。这就是我得到的:

git branch  (outputs that I'm on master)
git checkout -b foo
echo "next line" >> file (file is an existing file)
git add file (stages)
git checkout master
git status (shows that file has "next line" and is staged!!)
git commit (commits the changes that were staged on branch foo!!)
git checkout foo

这是踢球者。foo 现在不显示对工作目录或暂存中的文件所做的任何更改。

所以看起来 - 您所做的任何更改,包括修改文件和暂存,都发生在所有分支上。当您提交到特定分支时,这些更改将在所有其他分支上丢弃,除了您提交的分支。

这实际上是怎么回事?有人可以让我觉得这有意义吗?这听起来完全是古怪的行为,显然我没有得到让这成为明智之举的设计理念。

编辑明确的例子:

$ mkdir element
$ cd element
$ git init
Initialized empty Git repository in /home/dan/element/.git/
$ echo "one" >> one
$ git add one
$ git commit -m msg
[master (root-commit) 36dc8b0] msg
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 one
$ git checkout -b fire
Switched to a new branch 'fire'
$ echo "next line" >> one
$ git checkout master
M       one
Switched to branch 'master'
$ cat one
one
next line
$

这显然与 git pro 书中的内容相矛盾:

This is an important point to remember: Git resets your working directory to look like the snapshot of the commit that the branch you check out points to. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it.

4

2 回答 2

14

添加文件时,您在哪个分支上并不重要,只有在您提交文件时才重要。所以如果你这样做:

git add file
git checkout master
git commit

您已将文件提交到 master 分支。

这是一个完整的示例,带有输出。我们从一个新的存储库开始:

$ git init
Initialized empty Git repository in /home/lars/tmp/so/repo/.git/

此时,我们在master分支上,还没有添加任何文件。让我们添加一个文件:

$ date > file1
$ cat file1
Fri May 11 13:05:59 EDT 2012
$ git add file1
$ git commit -m 'added a file'
[master (root-commit) b0764b9] added a file
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 file1

太好了,我们现在有了一个master带有一次提交的分支 ( )。让我们创建新分支:

$ git checkout -b foo
Switched to a new branch 'foo'
$ git branch
* foo
  master
$ ls
file1

现在我们将添加一行到file1.

$ date >> file1
$ git status
# On branch foo
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   file1
#
no changes added to commit (use "git add" and/or "git commit -a")

这表明该文件已被修改,但尚未暂存。让我们暂存文件并提交它:

$ git add file1
$ git commit -m 'made a change'
[foo 761bed9] made a change
 1 files changed, 1 insertions(+), 0 deletions(-)

并重新运行git status

$ git status
# On branch foo
nothing to commit (working directory clean)

此时,文件如下所示:

Fri May 11 13:05:59 EDT 2012
Fri May 11 13:07:36 EDT 2012

如果我们切换回master分支,我们将看到没有第二行的文件的早期版本:

$ git checkout master
Switched to branch 'master'
$ cat file1
Fri May 11 13:05:59 EDT 2012

对文件的更改与提交它们的分支隔离。

在您更新的示例中,这...

$ git checkout master

...不会产生错误,因为此时两者中的“one”版本masterfire相同的。工作目录中的更改同样适用于任一版本。

于 2012-05-11T17:11:57.317 回答
7

暂存区 aka 索引对所有分支都是通用的,这解释了您的观察

于 2017-05-06T00:56:59.523 回答