Git 撤销以及取消跟踪操作

in #git8 years ago

撤销修改

1、已经修改,还没 git add

git checkout -- filePath  # 注意 “--”,其实不用也可以...

2、已经 add 到暂存区,但还没有提交(commit)

git reset HEAD file  

上面这个动作会将文件放回工作区,也就是修改了文件但是还没有add的状态,之后如果想丢弃修改就执行上面那种情况即可

3、已经commit(本地版本库),但没有push到远程仓库

使用

git reset --hard commit_id

这样就需要进行版本回退操作,首先,通过git log查看你想要回退到哪个版本,每次提交都会生成一个经过SHA1计算出来的id,看起来那个像是这个样子

git log  

commit 5f03edcd53148340f77deb0c81eb074cc5545c1a
Author: chendan <[email protected]>
Date:   Wed Sep 21 14:24:48 2016 +0800

    unfollow c

commit 5db80c9c4bdedd380ff9ee63220e3b6cba1b0aa9
Author: chendan <[email protected]>
Date:   Wed Sep 21 14:23:26 2016 +0800

    add c

5f03edcd53148340f77deb0c81eb074cc5545c1a 就是提交的 id,回退过程中只需要使用 id 的前几位即可

git reset --hard 5f03e

这样即可回退到unfollow c这个版本,当然,如果很确定我只是想回退到上一个(或n个)版本,直接使用git reset --hard HEAD^ 即可,其实HEAD表示的是当前版本,HEAD^就是上一个版本,HEAD^^就是上两个版本,以此类推

reset --hard操作的问题在于,当你回退到前第n个版本之后,通过git log操作就再也看不到前面这(n-1)次提交的 ID了,那如果后悔了,想会推到前(n-2)个版本(相对于一开始来说),则需要使用 git reflog 来查看命令历史,从中就可以得到我们需要的 commit id

4、已经 commit 且 push 到了远程仓库

对于不想被别人看到你的修改的情况来说
:) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :)

取消git对文件的追踪

常见的两种情况:
一、目标文件(夹)不是项目必须的,可以删掉(如log文件夹,每次运行之后会重新生成),但是不小心提交到远程仓库了(git开始跟踪这个文件的修改了)
二、文件是必须的,但是每个人的内容不一样(如一些数据库或者其他组件的配置文件),由创建项目的人初次提交(作为模板,当然更好的办法应该是直接提交一份.template文件)之后大家各自clone到本地,希望自己修改不会影响到远程仓库

一种方法

先将目标文件的追踪信息从git的数据库中删除,然后修改 .gitignore 文件,在其中将目标文件忽略,最后提交

git rm [-r] --cached logs/xx.log 

# .gitignore
logs/xx.log


git commit -m "We really don't want Git to track this anymore!"

这种方法将会删除掉远程仓库中的目标文件(不会删掉本地的文件),因此当别人他们本地项目的时候 git 会把他们本地的目标文件删掉

另一种不完美的办法

取消跟踪某个文件:

git update-index --assume-unchanged your_file_path

这样 git 不会删掉本地的文件,也不会将文件标记为删除(也就是提交到远程仓库之后远程仓库不会把这个文件删掉),之后 git 将不再会记录我们对这个文件的修改

再次继续跟踪某个文件

git update-index --no-assume-unchanged your_file_path

这个方法的问题在于:
1、所有的团队成员都必须对目标文件执行:git update-index --assume-unchanged <文件路径>。这是因为即使你让 Git 假装看不见目标文件的改变,但文件本身还是在 Git 的历史记录里的,所以团队的每个人在 fetch 的时候都会拉到目标文件的变更。(但实际上目标文件是根本不想被 Git 记录的,而不是假装看不见它发生了改变)
2、一旦有人改变目标文件之后没有 git update-index --assume-unchanged <文件路径> 就直接 push 了,那么接下来所有拉取了最新代码的成员必须重新执行 update-index,否则 Git 又会开始记录目标文件的变化。这一点实际上很常见的,比如说某成员换了机器或者硬盘,重新 clone 了一份代码库,由于目标文件还在 Git 的历史记录里,所以他/她很可能会忘记 update-index。

update-index的意图及正确用法

我们知道 Git 不仅仅是用来做代码版本管理的,很多其他领域的项目也会使用 Git。比如说我公司曾经一个客户的项目涉及到精密零件图纸文档的版本管理,他们也用 Git。有一种使用场景是对一些体积庞大的文件进行修改,但是每一次保存 Git 都要计算文件的变化并更新工作区,这在硬盘慢的时候延迟卡顿非常明显。

git update-index --assume-unchanged 的真正用法是这样的:

你正在修改一个巨大的文件,你先对其 git update-index --assume-unchanged,这样 Git 暂时不会理睬你对文件做的修改;
当你的工作告一段落决定可以提交的时候,重置改标识:git update-index --no-assume-unchanged,于是 Git 只需要做一次更新,这是完全可以接受的了;
提交+推送。

参考

Sort:  

Congratulations @taamcan! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

Click here to view your Board

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @taamcan! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.05
TRX 0.32
JST 0.082
BTC 64892.59
ETH 1765.07
USDT 1.00
SBD 0.42