Git 如何修复错误的合并,并将正确的提交重放到固定的合并上?
几次提交之前,我在解析合并时意外地将一个不需要的文件(Git 如何修复错误的合并,并将正确的提交重放到固定的合并上?,git,git-filter-branch,git-rewrite-history,git-rm,Git,Git Filter Branch,Git Rewrite History,Git Rm,几次提交之前,我在解析合并时意外地将一个不需要的文件(filename.orig)提交到了我的存储库中,直到现在我都没有注意到它。我想从存储库历史记录中完全删除该文件 是否可以重写更改历史记录,以便从一开始就不会将filename.orig添加到存储库中?这就是设计的目的。如果您的情况与问题中描述的情况不同,请不要使用此配方。此方法用于修复错误的合并,并将好的提交重放到固定的合并上。 虽然filter branch将执行您想要的操作,但这是一个相当复杂的命令,我可能会选择使用git-rebase
filename.orig
)提交到了我的存储库中,直到现在我都没有注意到它。我想从存储库历史记录中完全删除该文件
是否可以重写更改历史记录,以便从一开始就不会将
filename.orig
添加到存储库中?这就是设计的目的。如果您的情况与问题中描述的情况不同,请不要使用此配方。此方法用于修复错误的合并,并将好的提交重放到固定的合并上。
虽然filter branch
将执行您想要的操作,但这是一个相当复杂的命令,我可能会选择使用git-rebase
来执行此操作。这可能是个人喜好filter branch
可以在一个稍微复杂的命令中完成,而rebase
解决方案是一步一步地执行等效的逻辑操作
尝试以下配方:
#在错误合并位置创建并签出临时分支
git签出-b tmpfix
#删除错误添加的文件
git rm somefile.orig
#提交修改后的合并
修改最后一次提交
#回到主分支
切换到主分支
#将主分支重新移植到已更正的合并上
git-rebase-tmpfix
#删除临时分支
吉特分行-d tmpfix
(请注意,您实际上不需要临时分支,您可以使用“分离头”来完成此操作,但您需要记下由
git commit--amend
步骤生成的提交id,以提供给git rebase
命令,而不是使用临时分支名称。)如果此后您没有提交任何内容,只需gitrm
文件和gitcommit--amend
如果你有
git filter-branch \
--index-filter 'git rm --cached --ignore-unmatch path/to/file/filename.orig' merge-point..HEAD
将完成从合并点
到头
的每次更改,删除filename.orig并重写更改。使用--ignore unmatch
意味着如果出于某种原因更改中缺少filename.orig,则该命令不会失败。这是本文示例部分中推荐的方法
Windows用户注意:文件路径必须使用前斜杠您还可以使用:
git重置头文件/路径
这是最好的方法:只需确保先备份文件的副本即可 编辑 审查期间,编辑被不幸拒绝。
请参阅下面的Neons帖子,它可能包含有用的信息
例如,要删除意外提交到git存储库中的所有
*.gz
文件:
$ du -sh .git ==> e.g. 100M
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch *.gz' HEAD
$ git push origin master --force
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git gc --prune=now
$ git gc --aggressive --prune=now
那对我还是不起作用?(我目前使用的是git版本1.7.6.1)
不知道为什么,因为我只有一个主分支。不管怎么说,我终于把我的git回购真正清理干净了,我把它推到了一个新的空的、光秃秃的git存储库中
$ git init --bare /path/to/newcleanrepo.git
$ git push /path/to/newcleanrepo.git master
$ du -sh /path/to/newcleanrepo.git ==> e.g. 5M
(是的!)
然后我将其克隆到一个新目录,并将其.git文件夹移到这个目录中。e、 g
$ mv .git ../large_dot_git
$ git clone /path/to/newcleanrepo.git ../tmpdir
$ mv ../tmpdir/.git .
$ du -sh .git ==> e.g. 5M
(是啊!终于打扫干净了!)
在确认一切正常后,您可以删除
。/large\u dot\u git
和。/tmpdir
目录(可能在几周或几个月后,以防万一……)重写git历史记录需要更改所有受影响的提交ID,因此,参与该项目的每个人都需要删除旧的回购协议副本,并在清除历史记录后进行新的克隆。给it带来不便的人越多,您就越需要一个很好的理由来做这件事——您多余的文件并不会真的造成问题,但是如果您正在处理项目,如果您愿意的话,您最好清理Git历史记录
为了使其尽可能简单,我建议使用,这是一种比git过滤器分支更简单、更快的替代方法
,专门用于从git历史记录中删除文件。在这里,它使您的生活更轻松的一种方式是,它在默认情况下处理所有引用(所有标记、分支等),但速度也更快
您应该仔细遵循以下步骤:-但核心部分是:下载(需要Java 6或更高版本)并运行以下命令:
$ java -jar bfg.jar --delete-files filename.orig my-repo.git
将扫描您的整个存储库历史记录,并删除所有名为filename.orig
(不在您的存储库中)的文件。这比使用git filter branch
做同样的事情要容易得多
全面披露:我是BFG回购清理器的作者。为了将这一点添加到Charles Bailey的解决方案中,我刚刚使用git rebase-I从早期提交中删除了不需要的文件,它就像一个符咒。 步骤如下:
# Pick your commit with 'e'
$ git rebase -i
# Perform as many removes as necessary
$ git rm project/code/file.txt
# amend the commit
$ git commit --amend
# continue with rebase
$ git rebase --continue
简介:您有5种解决方案可用
原始海报上写着:
我不小心将一个不需要的文件提交到了我的存储库中
之前…我想从存储库历史记录中完全删除该文件
是吗
可以重写更改历史记录,以便永远不会删除filename.orig
首先添加到存储库中
有许多不同的方法可以完全从中删除文件的历史记录
吉特:
解决办法1:修订承诺 如果您不小心做了更改
# Pick your commit with 'e'
$ git rebase -i
# Perform as many removes as necessary
$ git rm project/code/file.txt
# amend the commit
$ git commit --amend
# continue with rebase
$ git rebase --continue
git rm <file>
git commit --amend --no-edit
git reset --hard HEAD^
git rm <file>
git commit --amend --no-edit
git rebase --continue
git diff master@{1}
git diff master@{1}
#!/bin/bash
if [[ $1 == "" ]]; then
echo "Usage: $0 FILE_OR_DIR [remote]";
echo "FILE_OR_DIR: the file or directory you want to remove from history"
echo "if 'remote' argument is set, it will also push to remote repository."
exit;
fi
FOLDERNAME_OR_FILENAME=$1;
#The important part starts here: ------------------------
git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch $FOLDERNAME_OR_FILENAME" -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
if [[ $2 == "remote" ]]; then
git push --all --force
fi
echo "Done."
You should probably clone your repository first.
Remove your file from all branches history:
git filter-branch --tree-filter 'rm -f filename.orig' -- --all
Remove your file just from the current branch:
git filter-branch --tree-filter 'rm -f filename.orig' -- --HEAD
Lastly you should run to remove empty commits:
git filter-branch -f --prune-empty -- --all
touch empty
git init
git add empty
git commit -m init
# 92K .git
du -hs .git
dd if=/dev/random of=./random bs=1m count=5
git add random
git commit -m mistake
# 5.1M .git
du -hs .git
git reset --hard HEAD^
git reflog expire --expire=now --all
git gc --prune=now
# 92K .git
du -hs .git