警告:由于您提到了一个拉取请求,我假设您正在推送到一个单独的分支,除了您之外没有其他人正在处理该分支。否则,通常不鼓励强制推送。
让我们假设一些状态:
$ touch fileA.py fileB.py fileC.py
$ git add .
$ git commit -m "my message"
$ git push
$ ls
fileA.py* fileB.py* fileC.py*
$ git ll
* 537443d - (HEAD -> my-branch) my message (9 seconds ago) <Aleksander Stelmaczonek>
0 0 fileA.py
0 0 fileB.py
0 0 fileC.py
注意:git ll是我自定义的命令别名,定义见文末。
要从提交中删除 fileC.py 并将其保留在工作目录中,您可以使用 git rm 命令,然后修改您的提交并重新推送(强制推送),用修改后的提交替换原始提交。请注意,默认情况下,此命令还会从磁盘中删除文件,您需要使用--cached 选项。
$ git rm -h
usage: git rm [<options>] [--] <file>...
-n, --dry-run dry run
-q, --quiet do not list removed files
--cached only remove from the index
-f, --force override the up-to-date check
-r allow recursive removal
--ignore-unmatch exit with a zero status even if nothing matched
现在:
$ git rm --cached fileC.py
rm 'fileC.py'
$ git status
On branch my-branch
Changes to be committed:
deleted: fileC.py
Untracked files:
fileC.py
$ git commit --amend -m "my message"
[my-branch beebdc1] my message
Author: Aleksander Stelmaczonek <Olek@TPOLEK.localdomain>
Date: Wed Nov 10 18:25:37 2021 +0100
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 fileA.py
create mode 100644 fileB.py
$ git ll
941acb2 - (HEAD -> my-branch) my message (13 seconds ago) <Aleksander Stelmaczonek>
0 0 fileA.py
0 0 fileB.py
$ ls
fileA.py* fileB.py* fileC.py*
$ git push --force
我想强烈强调如果有多个人在这个分支上工作,那么进行强制推送是一个非常糟糕的主意。潜在的问题不是那么容易解决的,尤其是对于新手而言。
一般来说,我强烈推荐阅读Git Book。它是免费的,而且写得很好。对于新手来说,值得一读的是第 1、2、3、7.1、7.2、7.3 和 7.7 章。
就个人而言,对于与创建和修改提交相关的所有内容,我通常只使用 GUI。找出最适合您的 GUI 工具。我用https://git-fork.com/。
这就是您可以使用我的git ll 命令 (and others) 增强 git 体验的方法:
git config --global alias.ll "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %Cblue<%an>%Creset' --abbrev-commit --date=relative --numstat"