添加和删​​除相同文件的状态

时间:2017-04-15 15:41:08

标签: git

我偶然发现了一个奇怪的现象,据我所知,我可以用这个脚本可靠地再现这个现象:

#!/bin/bash
rm -Rf repo
mkdir repo
cd repo
git init
mkdir folder
echo a > folder/a
echo b > folder/b
git add .
git commit -m "First commit."
rm folder/b
echo c > folder/c
git add .
git commit -m "Second commit."
cd folder
git checkout `git log --pretty=format:%H | tail -1` .
echo "###################################################################"
git status
echo "###################################################################"
rm *
git checkout `git log --pretty=format:%H | head -1` .
echo "###################################################################"
git status
echo "###################################################################"
git add .
echo "###################################################################"
git status
echo "###################################################################"

哈希只是为了让您更容易看到一个git status结束而另一个开始的位置。我把它放在pastebin上,这样我们就可以更容易地参考行号:https://pastebin.com/z8GgDpfw

它的输出是:

$ ./script.sh Initialized empty Git repository in /[...]/repo/.git/
[master (root-commit) 165986a] First commit.
 2 files changed, 2 insertions(+)
 create mode 100644 folder/a
 create mode 100644 folder/b
[master 241e479] Second commit.
 2 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 folder/b
 create mode 100644 folder/c
###################################################################
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   b

###################################################################
###################################################################
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   b

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    b

###################################################################
###################################################################
On branch master
nothing to commit, working directory clean
###################################################################

b显示为添加和删除都没有明显原因:它在repo,index和工作树中完全相同。 git add .神奇地清除git status

这是预期的行为吗?如果是这样:为什么?为什么不首先显示干净的git status而不必git add .执行?{/ p>

1 个答案:

答案 0 :(得分:2)

您所做的是将新文件添加到暂存区域,然后将其从工作副本中删除。这很容易复制。

$ git init repo
Initialized empty Git repository in /Users/schwern/tmp/repo/.git/
$ cd repo/
$ touch this
$ git add this
$ rm this
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   this

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    this

touch this在工作副本中创建了一个文件。 git add this将其复制到暂存区域。 rm this已从工作副本中删除了该文件,但该文件仍在暂存区

如果我git commit现在,this将被提交,尽管工作副本中缺少该git commitgit add -p将暂存区域中的任何内容转换为提交。

大多数情况下,您不必担心暂存区域,但是当您必须将复杂的更改分成多个提交时,它变得非常非常方便。像folder/b这样的命令成为创建更小,更集中的提交的非常强大的工具。

您遇到的是&#34;工作副本&#34;和#34;集结区&#34; (也称为&#34;索引&#34;或&#34;缓存&#34;)。工作副本是磁盘上的实际文件,如git add

暂存区域是构建下一个提交的位置。您可以将其视为临时目录。 git commit将工作副本中的文件复制到暂存区域。 HEAD占用暂存区域中的任何内容并将其转换为下一次提交。

这就是为什么你可以进行&#34;上演&#34;和&#34;未分期&#34;更改到同一文件。这意味着暂存区域中的版本与磁盘上的版本不同,后者与上一次提交中的版本(func reportCall(with UUID: UUID, updated update: CXCallUpdate) )不同。