如何 "Un-push" git 中的文件?
How to "Un-push" a file in git?
你好,我是 Git 的新手。我在我的分支上工作,我不小心提交并推送了一个我修改过的文件(但不希望出现在我的拉取请求中)。例如:我推了 fileA.py
、fileB.py
、fileC.py
。但是我只想要 fileA.py
和 fileB.py
在拉取请求中。
来自
- FileA.py
- FileB.py
- FileC.py
到
- FileA.py
- FileB.py
我找到的大部分答案都涉及删除 fileC.py
。我不想实际删除 fileC.py
,我仍然希望它在 repo 中只是像 master 中那样的未修改版本。有没有 git 命令来实现这个?感谢您的帮助!
在 Git 中,“取消推送”相当于 强制 推送您推送之前的内容。您是否应该 force 推送取决于几个因素,主要因素是其他人是否可能正在构建您已经推送的分支版本。通常在 public 回购中强制推送是不受欢迎的,而在私人回购中它在 共享分支 上不受欢迎(例如 main
、master
、develop
, 等等)
也就是说,在你的情况下,听起来你并不是真的想“取消推动”,而是“推动其他东西”(这也需要用力推动)。
如果您当前您的 分支已签出,并且您在刚刚提交的位置,并且如果可以重新提交-write your branch 因为没有其他人在使用它,那么这应该实现你想要的:
git reset --mixed @~1 # Go back to the previous commit; leave files alone
git add FileA.py FileB.py # Stage only the files you want to commit.
git commit -m "Add files for new thing"
git push --force-with-lease # Using --force-with-lease is usually best practice
第一行中的注释 --mixed
是多余的,因为默认重置是混合的。该行可以改为 git reset @~1
。我把它留在里面,所以从学习的角度来看它更清楚,因为你是 Git.
的新手
备选方案: 如果条件不允许(或不应该)强制推送您的分支,那么您可以:
- 通过还原之前的提交来创建新的提交,然后重新创建新的正确提交,并将这 2 个提交推出。
- 再提交一次删除您不想要的文件,然后将其推出。
警告:既然你提到了拉取请求,我假设你正在推送到一个单独的分支,除了你之外没有其他人在处理。否则,通常不鼓励用力推动。
让我们假设一些状态:
$ 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"
听起来您想替换推送的提交。 (不建议在多用户设置中像这样重写历史记录。)
首先,恢复到提交之前
git reset HEAD^
然后重新创建提交并推送新提交。您将需要使用武力。
git push --force-with-lease # A safer version of -f/--force
开始之前,您应该标记问题提交。
git tag bad
这使您可以在出现任何问题时轻松恢复原始状态。
git checkout mybranch # In case you changed away
git reset --hard bad
你好,我是 Git 的新手。我在我的分支上工作,我不小心提交并推送了一个我修改过的文件(但不希望出现在我的拉取请求中)。例如:我推了 fileA.py
、fileB.py
、fileC.py
。但是我只想要 fileA.py
和 fileB.py
在拉取请求中。
来自
- FileA.py
- FileB.py
- FileC.py
到
- FileA.py
- FileB.py
我找到的大部分答案都涉及删除 fileC.py
。我不想实际删除 fileC.py
,我仍然希望它在 repo 中只是像 master 中那样的未修改版本。有没有 git 命令来实现这个?感谢您的帮助!
在 Git 中,“取消推送”相当于 强制 推送您推送之前的内容。您是否应该 force 推送取决于几个因素,主要因素是其他人是否可能正在构建您已经推送的分支版本。通常在 public 回购中强制推送是不受欢迎的,而在私人回购中它在 共享分支 上不受欢迎(例如 main
、master
、develop
, 等等)
也就是说,在你的情况下,听起来你并不是真的想“取消推动”,而是“推动其他东西”(这也需要用力推动)。
如果您当前您的 分支已签出,并且您在刚刚提交的位置,并且如果可以重新提交-write your branch 因为没有其他人在使用它,那么这应该实现你想要的:
git reset --mixed @~1 # Go back to the previous commit; leave files alone
git add FileA.py FileB.py # Stage only the files you want to commit.
git commit -m "Add files for new thing"
git push --force-with-lease # Using --force-with-lease is usually best practice
第一行中的注释 --mixed
是多余的,因为默认重置是混合的。该行可以改为 git reset @~1
。我把它留在里面,所以从学习的角度来看它更清楚,因为你是 Git.
备选方案: 如果条件不允许(或不应该)强制推送您的分支,那么您可以:
- 通过还原之前的提交来创建新的提交,然后重新创建新的正确提交,并将这 2 个提交推出。
- 再提交一次删除您不想要的文件,然后将其推出。
警告:既然你提到了拉取请求,我假设你正在推送到一个单独的分支,除了你之外没有其他人在处理。否则,通常不鼓励用力推动。
让我们假设一些状态:
$ 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"
听起来您想替换推送的提交。 (不建议在多用户设置中像这样重写历史记录。)
首先,恢复到提交之前
git reset HEAD^
然后重新创建提交并推送新提交。您将需要使用武力。
git push --force-with-lease # A safer version of -f/--force
开始之前,您应该标记问题提交。
git tag bad
这使您可以在出现任何问题时轻松恢复原始状态。
git checkout mybranch # In case you changed away
git reset --hard bad