本地刪除文件後讓git服務器也刪除這個文件

在Git 2.0版本之前,本地刪除文件時,想讓git服務器也刪除這個文件,需要使用下面的命令來添加改動:

  • 直接使用 git rm 命令來刪除文件,不僅會刪除本地文件,還會自動添加改動。
  • 當使用shell自身的rm命令刪除文件時,可以執行下面的命令來添加改動:

    • git add -A
    • git add -u
    • 不要執行 git add . 命令

git rm

使用 git rm 命令可以從本地刪除文件,同時自動添加被刪除文件到git的staged區域,後續直接執行 git commit 即可,不需要先執行 git add 命令:

$ ls
delete_by_git_rm  delete_by_rm
$ git rm delete_by_git_rm
rm 'delete_by_git_rm'
$ ls
delete_by_rm
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    delete_by_git_rm

可以看到,執行 git rm delete_by_git_rm 命令後,用 ls 命令查看,沒有再看到 delete_by_git_rm 文件,該文件已經從本地刪除。而用 git status 命令查看,刪除 delete_by_git_rm 文件的這個改動已經添加到git的staged區域,等待被commit。那麼後續執行 git commitgit push 命令後,遠端服務器上的同名文件也會被刪除。其他人從服務器pull代碼,不會再看到這個文件。

git add -A

當使用 shell 自身的 rm 命令刪除本地文件時,這個改動不會自動添加到git的staged區域。使用 git status 命令查看,會提示"Changes not staged for commit":

$ rm delete_by_rm
$ git status
On branch master
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:    delete_by_rm

此時,需要使用 git add 命令來添加改動。
一般常用 git add . 命令來添加本地改動到staged區域,但是針對用shell自身rm命令刪除文件的情況來說,git add . 命令不會添加已刪除文件到staged區域,執行時會打印如下警告信息:

$ git --version
git version 1.9.1
$ git add .
warning: You ran 'git add' with neither '-A (--all)' or '--ignore-removal',
whose behaviour will change in Git 2.0 with respect to paths you removed.
Paths like 'delete_by_rm' that are
removed from your working tree are ignored with this version of Git.

* 'git add --ignore-removal <pathspec>', which is the current default,
  ignores paths you removed from your working tree.

* 'git add --all <pathspec>' will let you also record the removals.

Run 'git status' to check the paths you removed from your workingtree.

可以看到,在Git 1.9.1版本上,執行 git add . 後,再用 git status 查看,刪除的本地文件還是沒有添加到git的staged區域。如果我們沒有注意到這一點,後續執行 git commitgit push 命令提交到遠端服務器,那麼遠端服務器上的同名文件不會被刪除,其他人從服務器pull代碼還是會看到那個文件。

即,在Git 1.9.1版本上,用 rm 命令刪除本地文件後,要添加這個改動到git的staged區域,然後commit、push,遠端服務器纔會同步刪除這個文件,git add .命令不會把已刪除文件添加到git的staged區域。

參考上面執行 git add . 命令時打印的警告信息,可以使用 git add --all 選項來添加已刪除文件的改動,--all 也可以寫爲 -A,這兩者是等效的。在Git 1.9.1版本上,查看 man git-add 對 -A 選項的說明如下:

-A --all --no-ignore-removal
Update the index not only where the working tree has a file matching \<pathspec\> but also where the index already has an entry. This adds, modifies, and removes index entries to match the working tree.  
If no \<pathspec\> is given, the current version of Git defaults to "."; in other words, update all files in the current directory and its subdirectories. This default will change in a future version of Git, hence the form without \<pathspec\> should not be used.

git add -u

如果覺得要輸入大寫的A比較麻煩,也可以使用 -u 選項,該選項同樣會添加已刪除文件的改動:

$ git add -u
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    delete_by_rm

查看Git 1.9.1版本 man git-add 對 -u 選項的說明如下:

-u --update
Update the index just where it already has an entry matching \<pathspec\>. This removes as well as modifies index entries to match the working tree, but adds no new files.  
If no \<pathspec\> is given, the current version of Git defaults to "."; in other words, update all tracked files in the current directory and its subdirectories. This default will change in a future version of Git, hence the form without \<pathspec\> should not be used.

git add -Agit add -u 都可以添加已刪除文件的改動,它們的區別在於,-A 選項會添加新增的文件,而 -u 選項不會添加新增的文件。

注意:上面描述了Git 1.9.1版本上 git add . 命令不會添加已刪除文件的改動。但是在當前最新的Git 2.23版本上,git add .命令可以添加已刪除文件的改動。有一些Linux系統上可能還是使用老版本的git,爲了兼容,對於用shell自身的rm命令刪除文件的情況,建議都加上 -u 選項。

最後說一個突然發現自己記錄的知識已經過時的小故事

我在幾年前使用git的時候,記錄 man git-add 裏面對 -u 選項的說明如下:

-u, --update
Only match \<filepattern\> against already tracked files in the index rather than the working tree. That means that it will never stage new files, but that it will stage modified new contents of tracked files and that it will remove files from the index if the corresponding files in the working tree have been removed.  
If no \<filepattern\> is given, default to "."; in other words, update all tracked files in the current directory and its subdirectories.

這個說明跟上面Git 1.9.1版本 man git-add 裏面的說明有所差異,跟當前最新的Git 2.23版本 man git-add 裏面的說明更是差異巨大 (這裏沒有貼出Git 2.23版本的說明)。
同時 git add . 在不同版本上的行爲還不一樣,頓時有種日新月異、地覆天翻之感。
我不得不多次修改文章內容,添加Git版本號的說明,可以說是三易其稿。
我已經不記得之前使用的git軟件版本是多少,感覺像是過時很久的老古董。
經過查找,Git 1.7.1版本對 git add -u 選項的說明跟我的記錄一致,其鏈接是: https://git-scm.com/docs/git-...
我之前用的應該就是Git 1.7.1版本罷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章