This page looks best with JavaScript enabled

Git 实践 - 修改操作

 ·  ☕ 7 min read · 👀... views

工作区和版本库

  • 工作区:

就是你电脑文件夹能看到的目录,就如我创建的test文件夹就是一个工作区

1
2
3
leeif@leeif MINGW64 /e/git/test (master)
$ ls
git.txt  index.html  README.md
  • 版本库(Repository):

工作区有一个隐藏的目录文件.git,这个虽然在工作区目录下,但不算在工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

flex-axis

上一篇讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

  1. git add把文件添加进去,实际上就是把文件修改添加到暂存区;
  2. git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

ok,我们实践一下:

  • 首先新建一个文件test.txt,然后对git.exe进行修改,

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    $ git diff git.txt
    diff --git a/git.txt b/git.txt
    index 97fe984..a537f08 100644
    --- a/git.txt
    +++ b/git.txt
    @@ -2,4 +2,6 @@ Git is a version control system.
     Git is free software.
    
     Git is a distributed version control system.
    -Git is free software.
    \ No newline at end of file
    +Git is free software.
    +
    +add test add test
    \ No newline at end of file
    

  • 然后我们用git status查看一下状态:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 3 commits.
      (use "git push" to publish your local commits)
    
    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:   git.txt
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
            test.txt
    

    Git非常清楚地告诉我们,git.txt被修改了,而test.txt还从来没有被添加过,所以它的状态是Untracked

  • 现在,使用两次命令git add,把git.txttest.txt都添加后,用git status再查看一下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 3 commits.
      (use "git push" to publish your local commits)
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
            modified:   git.txt
            new file:   test.txt
    

    所以,暂存区的状态就变成这样了:

    flex-axis
  • git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

    1
    2
    3
    4
    
    $ git commit -m "updata&test "
    [master 0fbc057] updata&test
     3 files changed, 5 insertions(+), 1 deletion(-)
     create mode 100644 test.txt
    

    在检查下状态,如果你没在对工作区文件进行修改的话,工作区返回的状态就是clean

    1
    2
    3
    4
    5
    
    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 4 commits.
      (use "git push" to publish your local commits)
    nothing to commit, working tree clean
    

    现在版本库变成了这样,暂存区就没有任何内容了:

    flex-axis

小结:
暂存区是Git非常重要的概念,弄明白了暂存区,就弄明白了Git的很多操作到底干了什么!

管理修改

为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。

每次修改,如果不add到暂存区,那就不会加入到commit中。

例如:

  • 我们对git.txt进行两次修改,并在修改之间进行如下指令操作:

    第一次修改 -> git add -> 第二次修改 -> git commit

    没错,我们会发现第二次修改没有被提交。我们前面讲了,Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

  • 那怎么提交第二次修改呢?你可以继续git addgit commit,也可以别着急提交第一次修改,先git add第二次修改,再git commit,就相当于把两次修改合并后一块提交了:

    第一次修改 -> git add -> 第二次修改 -> git add -> git commit


注:提交后,用git diff HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别

撤销修改

每个人都会犯错,但重点在于你能不能及时改正,Git当然也知道这一点,所以它给了我们撤销修改这个机会。

  • 第一种情况,在没git add提交到暂存区时,撤销修改

    我对git.txt增加了一条错误信息,使用git diff查看一下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
     $ git diff HEAD -- git.txt
    diff --git a/git.txt b/git.txt
    index a537f08..246dfe2 100644
    --- a/git.txt
    +++ b/git.txt
    @@ -4,4 +4,6 @@ Git is free software.
     Git is a distributed version control system.
     Git is free software.
     add test add test
    
    +
    +Add an error message
    \ No newline at end of file
    

    我们再用git status查看一下状态:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 4 commits.
      (use "git push" to publish your local commits)
    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:   git.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
    

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

    ok, 我们试一下,执行:

    1
    
    $ git checkout -- git.txt
    

    然后,查看文件git.txt:

    1
    2
    3
    4
    5
    6
    7
    8
    
    $ cat git.txt
    Git is a version control system.
    Git is free software.
    
    Git is a distributed version control system.
    Git is free software.
    
    add test add test
    

    嗯,最后一行Add an error message果然撤销了

  • 第二种情况,你把修改文件提交到了暂存区,但在git commit之前

    我们给git.txt添加Add a second error message,并执行git add提交到暂存区,用git staus参看以下状态:

    1
    2
    3
    4
    5
    6
    7
    
    $ $ git status
      (use "git push" to publish your local commits)
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
            modified:   git.txt
    bash: $: command not found
    

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

    1
    2
    3
    
    $ git reset HEAD git.txt
    Unstaged changes after reset:
    M       git.txt
    

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

    现在,我们可以执行git status查看状态发现,暂存区是干净的,而工作区有修改,其实,现在就回到了我们上面第一种情况了,执行git checkout -- git.txt后,查看状态,发现工作区也干净了,也就达到撤销修改的目的了。

    1
    2
    3
    4
    5
    6
    7
    8
    
    $ cat git.txt
    Git is a version control system.
    Git is free software.
    
    Git is a distributed version control system.
    Git is free software.
    
    add test add test
    

小结:

  • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout – file。
  • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
  • 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考上一篇,不过前提是没有推送到远程库。

删除文件

在Git中,删除也是一个修改操作,我们实验一下,之前添加一个新文件test.txt到Git并且进行了git commit提交操作,可以看下log

1
2
3
4
5
6
7
$ git log --pretty=oneline
0fbc057e11b4ba59f3700a79d760e5af927a6a65 updata&test  //添加text.txt文件
9152d920e48515d79a32824efcbe14b3665a3e6d add distributed
f78f60960e2d59bd6fdc1a069e840c6d1f1c2566 add txt
01ce8dd6733f7f78e7611ef72f2a092417de0bca updata homepage
4db229de25fb4d0c325c98df9263b2c3d4d4607f add homepage
6010c7e80796b40d89e1135bc2c86ac217274015 initial commit

一般情况下,我们通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:

1
2
3
4
5
$ rm test.txt

# 查看目录 已经没了test,txt文件
$ ls
git.txt  index.html  README.md

习惯性查看下状态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)
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:    test.txt

no changes added to commit (use "git add" and/or "git commit -a")

发现Git已经知道我们进行了删除操作。

现在会出现两种情况:

  • 一种情况就是执行rm命令后,发现文件删除错误了,但好在版本库里还有,所以可以很轻松的把误删的文件恢复到最新版本:

    1
    
    $ git checkout -- test.txt
    

    git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

  • 另一种情况确定进行删除操作,并需要从版本库中删除该文件。因此,需要使用git rm命令,并执行git commit提交操作:

    1
    2
    3
    4
    5
    6
    7
    
    $ git rm test.txt
    rm 'test.txt'
    
    $ git commit -m "deleted test"
    [master a15cd98] deleted test
     1 file changed, 0 insertions(+), 0 deletions(-)
     delete mode 100644 test.txt
    

    现在,文件就从版本库中也删除了,就此消失不见~~~

命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

Share on

睡沙发の沙皮狗
WRITTEN BY
睡沙发の沙皮狗
👨‍💻 Backend Developer/📚 Learner/🚀 Opensource enthusiast

 

What's on this Page