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

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

查看文件的修改历史

git show 356f6def9d3fb7f3b9032ff5aa4b9110d4cca87e # 查看更改

git查询文件修改日期和时间

通过命令查询上一次修改时间:

git log -1 --format="%ad" -- path/to/file

通过命令查询文件夹下所有文件上一次修改时间:

git ls-tree -r --name-only HEAD | while read filename; do

echo "$(git log -1 --format="%ad" -- "$filename") $filename"

done

[怎么把git管理的文件显示为最后提交日期?]

历史版本查看和对比git show, git diff

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

对比不同版本git diff c0f28a2e 2e476412c34a63b213b

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

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

git reset命令

git reset --soft   {{some-commit-hash}}:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可。取消了commit。
git reset  --mixed  {{some-commit-hash}}(默认) :回退到某个版本,只保留源码,回退commit和index信息,即将这个版本之后的所有变更移动到“未暂存”的阶段。取消了commit ,取消了add。Your branch is ahead of 'origin/master' by 1 commit.不小心commit大文件,但是push失败,使用git log找到上一次的版本号,再使用git reset --mixed 版本号就可以了。
git reset --hard  {{some-commit-hash}}:彻底回退到某个版本,丢弃 {{some-commit-hash}}提交之后的所有变更,本地的源码也会变为上一个版本的内容。取消了commit ,取消了add,取消源文件修改(相当于checkout了)。

使用场景示例:

1 git reset --soft {{some-start-point-hash}}如果想把之前3次的提交,作为一次提交 git reset –soft {{some-start-point-hash}}

2 如果想编辑,以不同的顺序,重新暂存,重新提交文件—— git reset {{some-start-point-hash}}

3 如果想清除变更记录,可以使用清理命令:git reset –hard HEAD

查看日志命令git log与git reflog

git log命令显示你最近的提交信息。是相对于每个分支来说的,不同分支的commit操作都会记录在对应分支的git log中。

而git reflog显示的是所有head移动的信息。记住,它是在本地的,而不是你仓库的一部分,不会包含在推送(push)和合并中(merge)。

Note: git log按q结束。

git log

git log常用参数:

  • –author=“Alex Kras” ——只显示某个用户的提交任务
  • –name-only ——只显示变更文件的名称
  • –oneline——把每次提交间显示的信息压缩成缩减的hash值和提交信息,在一行显示。
  • –graph ——显示所有提交的依赖树。该选项会在输出界面的左手边用一种基于文本的图形表示法来显示历史。
    如果你只是浏览一个单独分支的历史,那么这个功能是没有用的。
  • –reverse ——按照逆序显示提交记录(最先提交的在最前面)
  • –after ——显示某个日期之后发生的提交
  • –before ——显示发生某个日期之前的提交
  • --all——显示全部分支的历史
  • --pretty 参数,可以用来创建高级自定义输出。例如,主管要求在每周五提交周报,每周五都运行一下这个指令: git log --author="Alex Kras" --after="1 week ago" --oneline,然后将输出结果编辑一下,发送给主管审核。
  • 其它参数:

查看文件的详细变更git log -p
git log -p 或者 git log -p filename 不仅显示提交说明、提交者以及提交日期,还会显示这每次提交实际修改的内容。
然后你就可以使用 less 中常用的检索命令即“斜杠”后面加检索词/{{在此处添加你的检索词}}),在变更内容日志中检索指定的关键词(使用小写的n跳到下一条检索结果,大写的N跳到上一条检索结果)。

查看文件中指定位置的变更git log -L 
命令示例:git log -L 1,1:some-file.txt
你可以使用 git blame filename 追查出文件中每一行是由谁变更的。
git blame 是一个非常强大的工具,但是又是无法提供足够的信息。
git log 提供了一个 -L 的选项。这个选项允许指定文件中的某些行。Git只会输出与这些行的变更日志。这有点像带焦点的 git log -p 。

查看尚未合并的变更git log --no-merges master
如果你曾经与很多小伙伴工作在同一个持久分支上,也许会有这样的经历,父分支(例如:master)上的大量合并同步到你当前的分支。这使得我们很难分辨哪些变更时发生在主分支,哪些变更发生在当前分支,尚未合并到master分支。
git log --no-merges master..可以解决这个问题。注意--no-merges 标志意味着只显示没有合并到任何分支的变更,master..选项,意思是指显示没有合并到master分支的变更(在master后面必须有..)。
你也可以运行 git show --no-merges master.. 或者 git log -p --no-merges master.. 命令(输出结果相同)来查看一下尚未合并的文件

单独查看当前分支上的 commit?

把从别的分支上 merge 过来的 commit 去掉

方式1:按范围

你可以通过传入一个范围来查询该范围内的提交。该范围由以下格式指定,其中<since>和<until>是提交引用:

git log <since>..<until>

当使用分支引用作为参数时,此命令特别有用。 这是一个简单的方法来显示两个分支之间的差异。 考虑以下命令:

git log dev..master

git log dev..master --oneline 或者 git log dev.. --oneline(当前分支是master时)表示包含所有不在dev分支中的主分支的提交。

[Git系列之git log高级命令]

方式2:推荐

去除多个分支时:git log --no-merges master ^dev1 ^dev2 --oneline

方式3:--first-parent

git log --first-parent --oneline 

这种如果有多个人操作master分支,master上有分叉,可能只会显示其中一条。

[How to get git logs of only current branch and just a merged commit]

[单独查看当前分支上的 commit?]

常用示例

git log --graph --pretty=oneline --abbrev-commit

效果:

*   7825a50 merge with no-ff
|\
| * 6224937 add merge
|/
*   59bc1cb conflict fixed
...

更容易分清master和其它分支,更容易找到回滚点。

git log --pretty=oneline 文件名 # 显示修改历史

git reflog

你提交了一个你不想要提交的代码,最后你通过使用硬重置(hard reset)使其回到了之前的状态。稍后,你意识到,在这个过程中你丢失了一些其他的信息,并想要退回或是至少能看一眼。git reflog命令可以帮你做到这一点。

git reflog显示了一个提交信息(b1b0ee9 – HEAD@{4}),这是我使用硬重置(hard reset)时丢失的那个。

皮皮Blog

git文件删除和恢复

{针对文件删除及恢复}
删除文件跟踪并且删除文件系统中的文件file git rm file
提交刚才的删除动作,之后git不再管理该文件git commit
删除文件跟踪但不删除文件系统中的文件file git rm --cached file
Note:--cached Use this option to unstage and remove paths only from the index.Working tree files, whether modified or not, will beleft alone.只是将文件从暂存区去除(不影响工作区对应的文件)。
[git-rm - Remove files from the working tree and from the index]
提交刚才的删除动作,之后git不再管理该文件。但是文件系统中还是有file。 git commit
[Git版本控制教程 - Git本地仓库:删除文件]

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

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

git rm 之后的文件如何还原

执行$git rm createGraph.py删除文件createGraph.py后,发现删除错了。
解决方案1:
$git status
...
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
    deleted:    createGraph.py
可以看到提示先使用git reset HEAD <file>...来unstage文件
$git reset HEAD createGraph.py
Unstaged changes after reset:
D    createGraph.py
再查看一下
$git status
...
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    deleted:    createGraph.py
可以看到提示先使用git checkout -- <file>...来丢弃文件的修改
$git checkout -- createGraph.py
这样就恢复了rm了的文件
$ls
createGraph.py
解决方案2:
git rm README
git status
$ git stash list
stash@{0}: WIP on master: bfcdf14 test git
#拿出来使用 git stash pop
git stash pop
[Git高级教程 :git stash]
解决方案3:
这时可以直接使用git log; git reset --hard "commit id"恢复到上一个commit,但是这样不好,我只想恢复删除的那一个文件,要是commit之间做了很多改动,恢复到上一个commit会将其它文件的修改都恢复了。要对单个文件修改。
首先查看该文件的历史版本信息:git log Default@2x.png

记录下需要恢复的commit版本号:如 9aa51d89799716aa68cff3f30c26f8815408e926
恢复该文件:git reset 9aa51d89799716aa68cff3f30c26f8815408e926 Default@2x.png
提交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

版本回退-撤销文件修改

本地增改许多文件想要丢弃掉/工作区修改文件后想回到修改前(add之前)

1 git checkout -- .   // 这个只能删除多个文件,不能文件夹

2 git clean -xdf // 删除新增的文件(未跟踪文件的删除)如果文件已经git add到暂存区并不会删除!

3 如果文件不多,当然也可以用rm filename / rm dir -rf
git clean 参数
    -n 不实际删除,只是进行演练,展示将要进行的操作,有哪些文件将要被删除。(可先使用该命令参数,然后再决定是否执行)
    -f 删除文件
    -i 显示将要删除的文件
    -d 递归删除目录及文件(未跟踪的)
    -q 仅显示错误,成功删除的文件不显示
注:
git reset 删除的是已跟踪的文件,将已commit的回退。
git clean 删除的是未跟踪的文件

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

本地不小心【git checkout .】后的抢救措施!

1 git没有后悔药了;
2 只能通过Pycharm历史记录功能找回,在项目的文件夹上右键 > local history > show history,可以看到和几分钟前自动保存的区别。

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

1 用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 reset  --mixed HEAD。

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

然后如果想丢弃工作区文件的修改git checkout -- readme.txt,当然也可以直接使用git reset  --hard HEAD。

2 如果只是想撤销git add(比如想添加exclude文件),可以使用

git rm --cached <file>      to unstage

不但修改了文件还从暂存区提交commit到了版本库 - 版本回退(commit之后,push之前)

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

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

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

$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
    append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
    add distributed

Note:

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

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

$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed

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历史,就可以更清楚地看到提交历史的时间线。

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

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

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

git reset HEAD^

Note:lz建议不要使用--hard,万一之前没有commit,而修改了工作区的文件,hard会使工作区的文件修改消失。

$ git reset --hard HEAD^
HEAD is now at ea34578 add distributed

这时readme.txt的内容就成了版本add distributed。我们用git log再看看现在版本库的状态:

$ git log
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
    add distributed

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

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

{这个是git reset --hard后,又反悔了,想回到修改后的状态}

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

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

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

git-head

改为指向add distributed:

git-head-move

然后顺便把工作区的文件更新了。所以你让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

第二行显示append GPL的commit id是3628164。git reset --hard回到这个版本号就ok了。

皮皮Blog

git 撤销文件追踪

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

问题

git忘记设置ignore,commit了不想commit的文件(比如大文件或者远程和本地想分别保留不同文件)。

如果直接把大文件放到忽略文件里,是不生效的,不会被ignore;直接删除掉也不好(毕竟有时不想删除),对于大文件,再push还是会有push慢的问题。

几种解决方案:

解决方案1-git reset

适用于这个文件是最近一次commit的

git reset  --mixed回退(取消commit ,取消add),再添加.gitignore再add 和 commit。

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

解决方案2-git rm --cached(小文件git push前去除跟踪推荐)

{这个删除了可能还是要上传的:git rm --cached will add the delete action of the file to the index, just like git add will add an add action.也就是说还是会添加这个文件到远程,然后再删除,所以对于大文件貌似还是一样要上传。}

1 Git取消跟踪某个文件:
$git rm -r --cached FILENAME
Note: -r主要是对目录,都加上就行(这个操作不会删除这个文件)
2 更新info/exclude或者.gitignore忽略掉目标文件

[Git版本控制教程 - Git本地仓库:忽略指定文件]
3 最后 git commit -m "dont track" 

成功之后会提示:

...

* file changed ...

delete mode ... FILENAME

Note: git rm后用git status查看时,会显示deleted:目标文件。但是如果本地这个文件改过了,删除的只是commit里面的记录,外面的不会真删除。

检查一下,git status,提示nothing commit...就说明成功删除文件的追踪。如果显示untracked file FILENAME,可能是ignore文件出错。

终极解决方案3

此方法适用于这个文件是前几次commit的

git filter-branch --tree-filter

如commit了一个EpipeCpu/ipch目录下的大文件, 现在要push但是仅想删去commit中的这个目录。
$git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch 大文件目录或名字 -r' --prune-empty --tag-name-filter cat -- --all
Rewrite 44a7e4ad5e52ff26306338fbba9a890c50ba9ba7 (1/1) (0 seconds passed, remaining 0 predicted)  
 rm 'EpipeCpu/ipch/algorithms-5512fb35/algorithms-c0d91126.ipch'
rm 'EpipeCpu/ipch/epipecpu-63fefe78/epipecpu-e9527547.ipch'
Ref 'refs/heads/master' was rewritten
将这个目录加入到了exclude中,再使用git push就不会上传那个目录下的文件了。
不过此方法有可能会带来一些问题:一定要尽可能少用这个功能,虽然他可以减少我们 git 目录的大小,但是这会对其他协作者产生极大的影响。所有受到影响的 commit 的 ID 都会被重写,另外如果 commit 像我这样有 GPG 签名的话,就无法执行这个操作了。
[从 git commit 中永久删除某个文件]

[如何删除github上的一个项目的内容,重新提交所有内容]

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

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 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 git@github.com:***

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 update-index

这种方法好像有问题,不推荐

git update-index --assume-unchanged <PATH>

[git忽略已经被提交的文件]

git revert 撤销中间某次提交

git revert 撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销
作为一次最新的提交
    * git revert HEAD                  撤销前一次 commit
    * git revert HEAD^               撤销前前一次 commit
    * git revert commit (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤销指定的版本,撤销也会作为一次提交进行保存。

git revert 和 git reset的区别 
1. git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。 
2. 在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。 
3. git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。

[git 优雅的撤销中间某次提交]

from:Git版本控制:Git查阅、撤销文件修改和撤销文件追踪_皮皮blog-CSDN博客_git 查看未合并文件

ref:git 撤销提交的文件

git reset简介

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值