Remove files from Git commit
我使用的是Git,我已经提交了一些文件
1 | git commit -a |
后来,我发现一个文件被错误地添加到提交中。
如何从上次提交中删除文件?
我认为这里的其他答案是错误的,因为这是一个将错误提交的文件从上一次提交移回临时区域的问题,而不取消对它们所做的更改。这可以像Paritosh Singh建议的那样:
1 | git reset --soft HEAD^ |
或
1 | git reset --soft HEAD~1 |
然后重置不需要的文件,以便将它们从提交中删除:
1 | git reset HEAD path/to/unwanted_file |
现在再次提交,您甚至可以重复使用相同的提交消息:
1 | git commit -c ORIG_HEAD |
注意!如果您只想从以前的提交中删除一个文件,并将其保存在磁盘上,请阅读上面Juzzlin的回答。
如果这是最后一次提交,并且您希望从本地和远程存储库中完全删除该文件,则可以:
修正标志告诉Git再次提交,但是"合并"(不是合并两个分支)这个提交和最后一次提交。
如注释所述,在这里使用
现有的答案都是关于从上一次提交中删除不需要的文件。
如果要从旧提交(甚至推送)中删除不需要的文件,并且不希望创建新提交,这是不必要的,因为该操作:
1。
找到您希望文件符合的提交。
1 | git checkout <commit_id> <path_to_file> |
如果要删除许多文件,可以多次执行此操作。
2。
1 | git commit -am"remove unwanted files" |
三。
找到错误添加文件的提交ID,这里说"35c23c2"
1 | git rebase 35c23c2~1 -i // notice:"~1" is necessary |
此命令根据您的设置打开编辑器。默认值是vim。
将最后一个提交(应该是"删除不需要的文件")移动到错误提交的下一行(在我们的例子中是"35c23c2"),并将命令设置为
1 2 | pick 35c23c2 the first commit fixup 0d78b28 remove unwanted files |
你应该在保存文件后表现良好。
完成:
1 | git push -f |
如果您不幸遇到冲突,必须手动解决。
正如被接受的答案所表明的那样,您可以通过重置整个提交来完成此操作。但这是一个相当严厉的方法。这样做的一个更干净的方法是保持提交,并简单地从中删除更改的文件。
1 2 | git reset HEAD^ -- path/to/file git commit --amend --no-edit |
这从本质上获取了先前提交中的文件版本,并将其添加到当前提交中。这不会导致净更改,因此文件可以从提交中有效地删除。
如果未在服务器上推送更改,则可以使用
1 | git reset --soft HEAD~1 |
它将重置所有更改并还原为一次提交返回
如果您推动了更改,请按照@charlesb回答的步骤操作。
使用rm删除文件将删除它!
您总是在git中添加提交,而不是删除,因此在本例中,请将文件返回到第一次提交之前的状态(如果文件是新的,则这可能是一个删除"rm"操作),然后重新提交,文件将消失。
要将文件返回到某个以前的状态:
1 | git checkout <commit_id> <path_to_file> |
或者将其返回到远程头的状态:
1 | git checkout origin/master <path_to_file> |
然后修改提交,您会发现文件已从列表中消失(而不是从磁盘中删除!)
1 2 | git checkout HEAD~ path/to/file git commit --amend |
下面将只对您想要的文件进行解压,这是OP要求的。
1 | git reset HEAD^ /path/to/file |
你会看到下面的内容…
Changes to be committed: (use"git reset HEAD ..." to unstage)
modified: /path/to/file
Changes not staged for commit: (use"git add ..." to update
what will be committed) (use"git checkout -- ..." to discard
changes in working directory)modified: /path/to/file
- "要提交的更改"是提交前文件的早期版本。如果文件不存在,这看起来像是删除。如果提交此更改,将有一个修订将更改恢复到分支中的文件。
- "Changes Not Staged for Commit"是您提交的更改,以及文件的当前状态
此时,您可以对该文件执行任何您喜欢的操作,例如重置为其他版本。
当您准备好提交时:
1 | git commit --amend -a |
或者(如果您有其他不想提交的更改)
1 2 | git commit add /path/to/file git commit --amend |
我将举例说明。让A、B、C连续3次提交。提交B包含一个不应该提交的文件。
1 2 3 4 5 6 | git log # take A commit_id git rebase -i"A_commit_ID" # do an interactive rebase change commit to 'e' in rebase vim # means commit will be edited git rm unwanted_file git rebase --continue git push --force-with-lease <branchName> |
使用GitGUI可以简化从先前提交中删除文件的过程。
假设这不是一个共享分支,您不介意重写历史,那么运行:
1 | git gui citool --amend |
您可以取消检查错误提交的文件,然后单击"提交"。
该文件将从提交中删除,但将保留在磁盘上。因此,如果您在错误添加文件后取消选中该文件,它将显示在未跟踪文件列表中(如果您在错误修改文件后取消选中该文件,它将显示在未提交列表中的更改中)。
1 2 | git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file> git commit -m"removed unwanted file from git" |
将保留本地文件。如果您也不希望在本地使用该文件,可以跳过--cached选项。
如果所有的工作都在您的本地分支上,您需要在以后的提交中保存该文件,就像有一个干净的历史记录一样,我认为这样做的一个简单方法可能是:
1 2 3 4 5 | git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file> git commit --squash <commit_id> git add <file_to_remove_from_commit_<commit_id>_which_added_file> git commit -m"brand new file!" git rebase --interactive <commit_id>^ |
然后,您就可以轻松地完成重新平衡,而无需记住更复杂的命令或提交消息或键入尽可能多的内容。
如果您想要保留提交(可能您已经花了一些时间编写了一个详细的提交消息,并且不想丢失它),那么您只想从提交中删除该文件,而不是从存储库中完全删除该文件:
1 2 | git checkout origin/<remote-branch> <filename> git commit --amend |
执行以下命令序列:
1 2 3 4 5 6 7 8 | //to remove the last commit, but preserve changes git reset --soft HEAD~1 //to remove unneded file from the staging area git reset HEAD `<your file>` //finally make a new commit git commit -m 'Your message' |
我只是想补充一下上面的答案,因为我必须运行一个额外的命令:
1 2 | git reset --soft HEAD^ git checkout origin/master <filepath> |
干杯!
对我有用,但仍然认为应该有更好的解决方案:
1 2 | $ git revert <commit_id> $ git reset HEAD~1 --hard |
只需在另一个提交中保留要放弃的更改,签出其他更改即可。
1 | $ git commit --amend // or stash and rebase to <commit_id> to amend changes |
1 2 | Changes to be committed: (use"git reset HEAD <file>..." to unstage) |
在本地分支中有相同的问题,我只想恢复一个文件。为我工作的是-
(下面的feature/target_分支是我所有更改的地方,包括我要为特定文件撤消的更改)
(来源/功能/目标分支是我要将更改推送到的远程分支)
(Feature/Staging是我的临时临时临时分支,我将从所有需要的更改(不包括对该文件的更改)中推出)
从我的源站/功能/目标分支创建本地分支-称为"功能/分段"
将我的工作本地分支功能/目标分支合并到功能/分段分支
签出feature/staging,然后git reset——软orig头部(现在,来自feature/staging'的所有更改都将被暂存,但未提交。)
取消对我以前签入但有不必要更改的文件的标记
将功能/分段的上游分支更改为源站/功能/目标分支
提交其余阶段性更改,并将其推到我的远程源站/功能/目标分支
实际上,我认为一个更快更简单的方法是使用git-rebase交互模式。
1 | git rebase -i head~1 |
(或者头4,你想走多远)
然后,使用"edit"而不是"pick"。我不知道"编辑"有多强大。
https://www.youtube.com/watch?V= 2DQOSJALN18
希望你会发现它有帮助。
如果你不再需要那个文件,你可以
1 2 3 | git rm file git commit --amend git push origin branch |
如果你还不把你的更改推到Git
1 | git reset --soft HEAD~1 |
它将重置所有更改并还原为一次提交返回
如果这是您最后一次提交,并且您希望从本地和远程存储库中删除该文件,请尝试以下操作:
1 2 | git rm <file> git commit --amend |
或者更好:
重置优先
1 | git reset --soft HEAD~1 |
重置不需要的文件
1 | git reset HEAD path/to/unwanted_file |
再次承诺
1 | git commit -c ORIG_HEAD |
如果您使用的是Github,并且还没有提交,那么Github桌面很容易解决这个问题:
这对我来说是有效的,可以将文件从bit bucket repo中删除,我最初将该文件推送到分支。
1 2 3 4 | git checkout origin/develop <path-to-file> git add <path-to-file> git commit -m"Message" git push |
如果您不小心在提交中添加了一个文件,可以执行如下操作
1 | git rm --cached path_to_file |
小心使用
如果要从以前的提交中删除文件,请使用筛选器
1 | git filter-branch --prune-empty --index-filter 'git rm --ignore-unmatch --cached"file_to_be_removed.dmg"' |
如果看到此错误:
无法创建新备份。以前的备份已存在于refs/original中/强制用-f覆盖备份
只需删除本地repo上的refs备份
1 | $ rm -rf .git/refs/original/refs |