分类: Git, Resource

Git Basic – Undoing Changes






Git basic – undoing changes 【撤销改变】

在我们进入正题之前,首先让我做一点小小的解释,git 和 github

git,是一个一个非常强大的版本管理工具。Github则是一个基于Git的日益流行的开源项目托管库。所以我们这里是解释关于git 的使用,而不是github.

github这里可以理解,作为一个remote 服务器,在线的帮你托管你在线下的代码,方便的与其他人共享。所以我们这里所说的undoing changes是指在git 里面,在你自己的电脑里面撤销改变。而且我们想提示你,对于remote server,请你有很清楚的理解,对于 git pull & git checkout & git fetch 之间的不同。

基本上,git pull 和 git fetch 是对于git remtoe的命令行,简单说是用于与github进行沟通,而不是我们这里所说的本地处理。git pull = git fetch + git merge (两者简单的区别),当然在发散一点点,你也应该明白git pull & git checkout 还有 git clone 的区别。(这里我们就不在解释下去,有兴趣你可以去google一下,有很多很详细的解释和例子)

好了,我们在说“本地” 的undoing changes (撤销改变)

对于本地的undoing changes, 我们从三个点来说明,

  1. 复原回上一个版本 –
  2. 复原staging version
  3. 复原commit version

复原回上一个版本

命令: git checkout

例子,你修改了当下的文件,然后你发现,你不需要修改,或者之前的版本的才是对的,你需要找回之前版本的那个文件。例如:

git status
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: changes.txt
#

按照 git stauts 你修改了changes.txt,但是你要复原会之前你未做改变的changes.txt文件

$ git checkout -- changes.txt

git checkout 会复原会之前的文件,覆盖你所做的修改(注意:你最近的修改,将会丢失)

复原staging version

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

如上图,你已经staging 最近的改变,然后你觉得需要复原。

$ git reset HEAD README.txt
README.txt: locally modified
$ git status
# On branch master
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: README.txt
#

用 git reset HEAD , 文件将会un commit ,然后你可以继续修改。

复原commit version

对于复原commit version ,比之前的要麻烦一点,在说明怎么复原之前,让我们下说明一个简单的知识点,git 如何保证和tracking每个verion.

git 赋予了每个commit version一个hash-key,然后作为快照(snapshot)存储起来,里面有每次改变的具体信息,如修改者,时间,修改的介绍,等等。(如下图)

hash key 是按照文件的内容生成,每个文件都会保存前一个version  tree 的hask key.所以任何内容的修改,将对hash-key进行改动,hask key的改变,将改变整个veriosn tree,所以这里决定了,我们不能随意的改变已经commit了的文件的内容。

但是由于最后一次commit的内容其hash-key 还没有被其他version 作为参照,我们能够改变最后一次的commit.

(理解关于git 的hash key对于对git 的运行方式很重要)

Screen Shot 2013-07-20 at 2.12.47 PM

我们可以用 $ git commit –amend,对最后一次的commit进行修改:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

用git log,你会发现,git 只存储了一次commit.

如果你有兴趣,这里有git 的官方文件,对上面讲的内容进行说明
Git-Basics-Undoing-Things#Changing-Your-Last-Commit

最后送上一些高级小技巧

– check out 之前版本的文件

git log
//找出之前版本的hash-key
git checkout (hashkey) --filename

git 会自动checkout 对应hash-key 版本的相关文件

git revert – git revert <hash-key>

Screen Shot 2013-07-21 at 11.27.38 PM

 

Git revert 和 Reset 的区别

Git Reset

  • Soft (改变repo,现有修改文件不改变 – Staging and working copy stay )
  • Hard (所有改变复原会之前文件,重写,现在消除有改变)
  • Mix (default) (改变repo,改变staging , 现有working copy 不改变)

查找现有pointer,reset pointer :

cat .git/HEAD
ref: refs/heads/master
cat .git/refs/heads/master
5c86efadi12daidadfadslkl... //现有版本hash-key

//soft reset
git reset --soft <之前版本hash-key>
cat .git/refs/heads/master
//pointer 重置回<之前版本hash-key>
git status
//还保有最近的所有改变

 

//mixed reset

git reset --mixed < 之前版本hash-key>;
git status 
//staging 被清空,现有working copy 还保存;

git reset --hard < 之前版本hash-key>;
git status 
//重置所有改变,如同时间倒退,回到之前版本。所以之后改变会被消除

Reference : https://www.atlassian.com/de/git/tutorial/undoing-changes




发表评论

Webmentions

  • Git 基础复习 | Ian's Blog

    […] Git Basic – Undoing Changes […]