Git版本控制教程 - Git查阅、撤销文件修改和撤销文件追踪

http://blog.csdn.net/pipisorry/article/details/47867097

查看文件的修改历史

git log --pretty=oneline 文件名 # 显示修改历史[Git高级教程:git log与git reflog]

git show 356f6def9d3fb7f3b9032ff5aa4b9110d4cca87e # 查看更改

历史版本对比

查看日志git log

查看某一历史版本的提交内容git show 4ebd4bbc3ed321d01484a4ed206f18ce2ebde5ca,这里能看到版本的详细修改代码。

对比不同版本git diff c0f28a2ec490236caa13dec0e8ea826583b49b7a 2e476412c34a63b213b735e5a6d90cd05b014c33

[Git高级教程git log与git relog]

git reset命令参数

包括 --mixed,--soft --hard等,其中--mixed为默认方式,他们之间的区别如下
git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息
git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可
git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容
git reset -soft :取消了commit  
git reset -mixed(默认) :取消了commit ,取消了add
git reset -hard :取消了commit ,取消了add,取消源文件修改

Note :lz提示,如果是想恢复本地文件内容,则使用--hard参数;如果只是commit后(如提交了一个大文件,上传太慢或者出错,后悔提交了,想先ignore这个大文件再作提交)想撤销这次的commit,返回上一个commit,则用--mixed或不用参数。

push之前可以使用git diff origin/dev...HEAD --name-status查看要push的内容有没有改变。

Note: lz教你一招,加入linux命令grep:git diff origin/dev...HEAD --name-status | grep '.exe'这样就可以查找某个大文件如exe文件的变化了。

重置文件

在git中,有3种类型的重置。重置是让文件回到git历史中的一个特定版本。

  1. git reset –hard {{some-commit-hash}} —— 回退到一个特定的历史版本。丢弃这次提交之后的所有变更。
  2. git reset {{some-commit-hash}}—— 回滚到一个特定的历史版本。将这个版本之后的所有变更移动到“未暂存”的阶段。这也就意味着你需要运行 git add . 和 git commit 才能把这些变更提交到仓库.
  3. git reset –soft {{some-commit-hash}} ——回滚到一个特定的历史版本。将这次提交之后所有的变更移动到暂存并准备提交阶段。意味着你只需要运行 git commit 就可以把这些变更提交到仓库。

这些命令似乎并没有什么用处,但当你尝试着将文件在不同版本间移动时,使用它们会非常方便。

我平时使用重置的一些用例如下:

  1. 如果想清除变更记录,可以使用清理命令——git reset –hard HEAD (最常用)
  2. 如果想编辑,以不同的顺序,重新暂存,重新提交文件—— git reset {{some-start-point-hash}}
  3. git reset –soft {{some-start-point-hash}}如果想把之前3次的提交,作为一次提交 git reset –soft {{some-start-point-hash}}

git删除文件

删除文件跟踪并且删除文件系统中的文件file git rm file
提交刚才的删除动作,之后git不再管理该文件git commit
删除文件跟踪但不删除文件系统中的文件file git rm --cached file
提交刚才的删除动作,之后git不再管理该文件。但是文件系统中还是有file。 git commit
[ Git版本控制教程 - Git本地仓库:删除文件]

皮皮Blog



版本回退-撤销文件修改

工作区修改一个文件后,又想回到修改前

1. 当然可以直接手动再在工作区中将文件修改回去

2. 修改后,通过命令git status查看

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

这时Git会告诉你,git checkout -- file可以丢弃工作区的修改:

$ git checkout -- readme.txt

Note:

1. git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

2. 命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。总之,就是让这个文件回到最近一次git commitgit add时的状态。

3. 工作区、暂存区的概念不清楚的可见于Git版本控制教程 - Git本地仓库

如果在工作区中修改了文件还git add到暂存区(但是在commit之前)

git status查看一下,修改只是添加到了暂存区,还没有提交:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   readme.txt
#

Git同样告诉我们,用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区

$ git reset HEAD readme.txt
Unstaged changes after reset:
M       readme.txt

git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

再用git status查看一下,现在暂存区是干净的,工作区有修改。

然后丢弃工作区的修改
$ git checkout -- readme.txt

$ git status
# On branch master
nothing to commit (working directory clean)

不但修改了文件还从暂存区提交到了版本库 - 版本回退

版本回退可以回退到上一个版本。不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程。Git是分布式版本控制系统。

在工作中对某个文件(如readme.txt)进行多次修改交commit。

可以通过版本控制系统命令告诉我们提交的历史记录,在Git中,我们用git log命令查看:

$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 15:11:49 2013 +0800

    append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date:   Mon Aug 19 17:51:55 2013 +0800

    wrote a readme file
Note:

1. git log命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是wrote a readme file

2. 如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

3. 你看到的一大串类似3628164...882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。

4. 每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具(如GitX、github的客户端、pycharm)查看Git历史,就可以更清楚地看到提交历史的时间线。

皮皮Blog

现在我们想要把readme.txt回退到上一个版本

如“add distributed”的那个版本,怎么做呢?首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

现在,我们要把当前版本“append GPL”回退到上一个版本“add distributed”,就可以使用git reset命令:

$ git reset --hard HEAD^ HEAD is now at ea34578 add distributed
这时readme.txt的内容就成了版本 add distributed
我们用 git log再看看现在版本库的状态:
$ git log
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <[email protected]>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date:   Mon Aug 19 17:51:55 2013 +0800

    wrote a readme file

最新的那个版本append GPL已经看不到了!

恢复文件后,要是我们又想回到修改后的文件呢?(命令行窗口还没有被关掉)

只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPLcommit id3628164...,于是就可以指定回到未来的某个版本:

$ git reset --hard 3628164
HEAD is now at 3628164 append GPL

版本号没必要写全,前几位就可以了,Git会自动去找。

Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL

Git版本控制教程 - Git查阅、撤销文件修改和撤销文件追踪_第1张图片

改为指向add distributed

Git版本控制教程 - Git查阅、撤销文件修改和撤销文件追踪_第2张图片

然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

恢复文件后,要是我们又想回到修改后的文件呢?(命令行窗口早就关掉了)

想恢复到新版本怎么办?找不到新版本的commit id怎么办?当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。

Git提供了一个命令git reflog用来记录你的每一次命令:[Git高级教程:git log与git reflog]

$ git reflog
ea34578 HEAD@{0}: reset: moving to HEAD^
3628164 HEAD@{1}: commit: append GPL
ea34578 HEAD@{2}: commit: add distributed
cb926e7 HEAD@{3}: commit (initial): wrote a readme file

第二行显示append GPL的commit id是3628164,现在,你又可以乘坐时光机回到未来了。


本地文件被旧的远程文件覆盖怎么撤销修改

git reflog ,找到同步前的提交,git reset 就可以了

恢复单文件的另种解决方法

首先查看该文件的历史版本信息:git log [email protected]
记录下需要恢复的commit版本号:如 9aa51d89799716aa68cff3f30c26f8815408e926
恢复该文件:git reset 9aa51d89799716aa68cff3f30c26f8815408e926 [email protected]
提交git:git commit -m "revert old file"
测试了一下,发现文件根本没有改动,只是有unstaged commit的提示(说明一下,我是在windows环境下使用git客户端,linux不知道是不是同样的问题),并且,一旦执行“git add .”,所有暂存区中的变化全都消失了。
尝试执行git checkout命令,因为这个命令平时只适应于将文件恢复到上次递交的状态,而不能选择递交的版本。
虽然执行完毕后什么提示都没,但是查看文件可以看到,文件已经被修改为历史版本了。
总结:git将单个文件恢复到历史版本的正确方法如下:
   git reset commit_id 文件路径
   git checkout -- 文件路径
[ GIT 恢复单个文件到历史版本]

皮皮Blog



git 撤销文件追踪

git忽略已经被提交的文件/文件夹

{git 对于 已经添加到版本库的文件设置忽略}

问题

git commit时候忘记设置ignore了,于是commit了一个相当大的文件,git push时候,因为要push大文件,可能会出错,也可能push好久还没好。
如果直接删除掉大文件,再push还是同样问题;如果把大文件放到忽略文件里,再push,还是这样的问题不变。

几种解决方案:

使用git reset回滚commit操作

像上面撤销文件修改那样git reset操作解决。
但是如果是commit很多次提交后才发现commit了大文件,回滚到大文件之前的同时也回滚了不想回滚的其它commit,这样不好。
并且这样有可能git reset操作之后有时候还是会提交上次提交失败的大文件,可能还在上一个commit中大文件没有ignore(这个是通过git diff origin/dev...HEAD --name-status查到大文件还是会上传push看到的),git reset方法似乎不是最保险。

使用git rm --cached

lz找到下面的另一种方法,即不是回退,而是将commit后的文件直接从commit中删除掉,这样就不用管是哪次的commit出了大文件错误问题了。
Git取消跟踪某个文件:git commit某个文件后又不想跟踪它了(比如取消已经commit的大文件,不想push到远程),可以通过下面的方法解决
$ git rm --cached FILENAME
如果后面跟的是目录就加上个 -r  就行,(这个操作不会删除这个文件) git rm -r --cached DIR_NAME
然后 更新info/exclude或者.gitignore忽略掉目标文件,不知道怎么操作的可参见[ Git版本控制教程 - Git本地仓库:忽略指定文件]
最后  git commit -m "dont track"     还是  git commit --amend -CHEAD ?
成功之后会提示:
...
* file changed ...
delete mode ... FILENAME
检查一下,git status,提示nothing commit...就说明成功删除文件的追踪。如果显示untracked file FILENAME,可能是ignore文件出错,解决参见[ Git版本控制教程 - Git本地仓库:忽略指定文件]。
当然如果你后悔了,从ignore文件中删除FILENAME,再直接git add .就可以了,然后git commit,可能会提示没有什么变化。
[ .gitignore not working]
[ 处理GitHub不允许上传大于100M文件问题]
[ git忽略已经被提交的文件]

终极解决方案:本地重建并取代远程

lz碰到一个很烦人的,git rm --cached bigfile并且ignore后,使用git diff查看明明没有大文件,所有要提交的大文件都是D(delete模式),难道delete的文件也要上传?还是之前add大文件后再git rm cached后有两个操作,add再delete,可是git diff里面并没有add大文件,不知道为什么总是有那个大文件上传,总是!用了无数方法总是有这个大文件targetopinion/dist/TargetOpinionMain.exe:
Git版本控制教程 - Git查阅、撤销文件修改和撤销文件追踪_第3张图片
git diff查看是没有TargetOpinionMain.exe文件add的,也是奇怪。ps:lz曾经将这个大文件从nlp/dist移动到nlp/targetopinion/dist中,然后路径中git rm --cached不能作用于dist,而可以作用于targetopinion/dist,但是怎么说那个targetopinion/dist中的exe大文件是没有的!可是它总是有!搞了好久,lz只能采取下面的极限方法了:
删除本地nlp目录下的.git文件夹
重新设置本地git管理:git init
git remote add origin [email protected]:***
git add .
git commit -m 'init commit'
git push -u --force origin 分支名
这里是强制提交,本来要git pull的,但是这样可能覆盖本地文件,要是完全不想要远程的文件了,可以这样,用本地取代远程的文件(结果导致远程主机上更新的版本被覆盖)。git push见[ Git版本控制教程 - Git远程仓库:--force选项]
这个其实不就是“如何删除github上的一个项目的内容,重新提交所有内容”吗?[ 如何删除github上的一个项目的内容,重新提交所有内容]

修改最后一次提交git commit --amend

{还有一种有条件但是更简单快捷的解决方案:git commit --amend 修改上一次的提交信息,这是最快最好的方法,不过如果不是针对上一次提交那就不好了!}
有时候用 git commit -m 提交时,可能没写好或者误操作导致提交的信息不合适,但你还没有 push 到远程分支时,可以使用 git commit --amend 修改上一次的提交信息。
有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交:
$ git commit --amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
[ git commit –amend 修改还未提交到远程分支的 commit 信息]

git filter-branch --tree-filter

没试过这个方法,感觉不行
[ 如何删除github上的一个项目的内容,重新提交所有内容]

git update-index

这种方法好像有问题,不推荐
git update-index --assume-unchanged <PATH>
[ git忽略已经被提交的文件]
from: http://blog.csdn.net/pipisorry/article/details/47867097
ref: git 撤销提交的文件
git reset简介

你可能感兴趣的:(git,撤销修改)