git版本库
仓库(repository):是本地磁盘的一个目录,目录的所有项目文件都可以被git进行控制管理。
初始化仓库:
git init
此时的仓库目录结构如图:
工作区:除了隐藏目录.git(版本库)之外的所有文件。
暂存区:工作区的文件先要提交到版本库的暂存区中,然后由暂存区提交完成。
查看仓库的状态:
git status
此时仓库中没有提交的文件,提示创建或复制一个文件添加到版本库进行追踪,先在工作区中创建一个文件text.txt,然后添加进暂存区
文件的状态有:
untracked
:不受版本库控制追踪modified
:受控制并且已被修改staged
:受控制,已被修改,并且git add
到了暂存区committed
:从暂存区已经git commit
到了本地仓库unmodified
:提交到本地仓库未修改或者从远程仓库克隆下来
添加文件:
git add <文件名>
此时仓库中把工作区的版本添加进了暂存区,提示暂存区中有新的文件可供提交
提交文件:
git commit -m "备注" <文件名>
此时仓库中暂存区会提交最终版本并生成一个commit id
,工作区是干净的,没有文件可供提交。
查看提交历史记录:
git log
看起来比较繁琐有commit id
、作者、日期、备注等,可以用一行显示commit id
、备注等
git log --pretty=oneline
git reflog
通过git reset
重置的文件,重置HEAD版本之后的改动记录全部没了,可以通过git reflog
找回
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git reflog
f981959 (HEAD -> master) HEAD@{0}: commit: “delete ti.txt
8235eee HEAD@{1}: commit: ti
fa77183 HEAD@{2}: commit: third edit
ce0fdd0 HEAD@{3}: reset: moving to ce0fdd06
c2b655d HEAD@{4}: reset: moving to c2b655d15
c2b655d HEAD@{5}: commit: repired conflict
b16e8e1 HEAD@{6}: reset: moving to b16e8e14ccb603f5d1a9ae05aa69e771c1b2ee41
b16e8e1 HEAD@{7}: reset: moving to b16e8e14ccb
ce0fdd0 HEAD@{8}: reset: moving to ce0fdd067f536c
b16e8e1 HEAD@{9}: reset: moving to b16e8e14ccb603
ce0fdd0 HEAD@{10}: reset: moving to HEAD^
b16e8e1 HEAD@{11}: reset: moving to b16e8e14ccb603f5d1a9ae
ce0fdd0 HEAD@{12}: reset: moving to HEAD^
b16e8e1 HEAD@{13}: commit: third edit
ce0fdd0 HEAD@{14}: reset: moving to HEAD^
55d1970 HEAD@{15}: commit: third edit
ce0fdd0 HEAD@{16}: commit: second edit
39d4917 HEAD@{17}: commit (initial): first edit
版本回退与修改
首先,我们修改三次文件,并提交到版本库,文件内容如下:
commit id |
39d4917a3cb | ce0fdd067f53 | 55d1970077 |
---|---|---|---|
内容 | first edit | first edit second edit | first edit second edit third edit |
备注 | first edit | second edit | third edit |
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
55d1970077eea3d750612d26b41eba84ad9d10b0 (HEAD -> master) third edit
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
由上图可知,(HEAD -> master)指向我们当前版本,若要回退上一个版本就是HEAD^
,倒退二个版本就是HEAD^^
,倒退三个版本就是HEAD^^^
,以此类推倒退100个就是HEAD~100
。同样我们也可以使用他们的commit id
来进行回退。
git checkout回退
git checkout -- <文件名>
此时我们修改test.txt,文件添加“fourth edit”,可是当我们想用git add
添加到暂存区时突然后悔了,想撤回工作区中的修改:
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git checkout -- test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
nothing to commit, working tree clean
此时将暂存区的内容恢复到工作区并更新了暂存区,查看test.txt中的文件被修改成third edit之后的内容,工作区是干净的,没有文件提交。(在Git 2.23之后被git restore
替换)
git restore回退
git-restore用于从索引或其他提交还原工作树中的文件。此命令不会更新您的分支。该命令还可用于从另一个提交还原索引中的文件。
git restore <file>
Git2.23版本之后添加的,和git checkout -- <file>
一样将暂存区的内容恢复到工作区,为了解决git checkout
的负担。
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git restore test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
nothing to commit, working tree clean
当我们修改文件test.txt,增加“fourth edit”并git add
到暂存区,此时我们想要撤回暂存的内容,用当前提交版本HEAD覆盖暂存区:
git restore --staged <file>
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git add test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git restore --staged test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
此时暂存区被HEAD覆盖,工作区文件没有被修改,恢复到了git add
前的状态。若要恢复工作区原状,使用git restore <file>
。
如果未指定,则工作树的默认还原源是索引,索引的默认还原源是 HEAD
。同时指定--staged
暂存区和--worktree
工作区, --source
还必须指定。同时使用HEAD还原暂存区和工作区:
git restore --source=HEAD --staged --worktree test.txt
git restore -s@ -SW hello.c
还原全部“*.txt”:
git restore '*.c'
还原当前目录的所有文件:
git restore .
git restore :/
git revert回退
git-revert关于进行新的提交,该提交将还原其他提交所做的更改。
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git revert ce0fdd067f536cf5d2d1f76
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
error: could not revert ce0fdd0... second edit
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master|REVERTING)
$ git add test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master|REVERTING)
$ git commit -m "repired conflict" test.txt
[master c2b655d] repired conflict
1 file changed, 4 insertions(+), 1 deletion(-)
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
c2b655d1568416ef9b99cc59083c541d7ac5682d (HEAD -> master) repired conflict
b16e8e14ccb603f5d1a9ae05aa69e771c1b2ee41 third edit
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
通过git revert
还原之后可能会发生冲突,会再次进行提交,追加一个HEAD记录
git reset回退
git-reset是关于更新分支,移动提示以便从分支中添加或删除提交。此操作更改提交历史记录。
git reset
也可以用于还原索引,与重叠git restore
。
当前在C,回退到second edit:((git reset
与git --mixed
等效,默认–mixed))
工作区(working) | 暂存区(index) | HEAD | |
---|---|---|---|
git reset --soft <HEAD或者commitid> |
A | B | C |
git reset --mixed <HEAD或者commitid> |
A | C | C |
git reset --hard <HEAD或者commitid> ` |
C | C | C |
git reset --soft <HEAD或者commitid>
回退到指定的版本,并且移动HEAD到指定的版本,指定版本之后的改动记录删除,工作区和暂存区没有改动。还可以使用git commit
对暂存区向HEAD覆盖:
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
55d1970077eea3d750612d26b41eba84ad9d10b0 (HEAD -> master) third edit
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git reset --soft HEAD^
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git reflog
ce0fdd0 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
55d1970 HEAD@{1}: commit: third edit
ce0fdd0 (HEAD -> master) HEAD@{2}: commit: second edit
39d4917 HEAD@{3}: commit (initial): first edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git commit -m "third edit" test.txt
[master b16e8e1] third edit
1 file changed, 2 insertions(+), 1 deletion(-)
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
b16e8e14ccb603f5d1a9ae05aa69e771c1b2ee41 (HEAD -> master) third edit
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
git reset --mixed <HEAD或者commitid>或者git reset <HEAD或者commitid>
回退到指定的版本,并且移动HEAD到指定的版本,指定版本之后的改动记录删除,暂存区被指定的版本覆盖,工作区没有改动。还可以使用git restore
对暂存区向工作区覆盖:
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
b16e8e14ccb603f5d1a9ae05aa69e771c1b2ee41 (HEAD -> master) third edit
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git reset HEAD^
Unstaged changes after reset:
M test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 (HEAD -> master) second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git restore test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
nothing to commit, working tree clean
git reset --hard <HEAD或者commitid>
回退到指定的版本,并且移动HEAD到指定的版本,指定版本之后的改动记录删除,暂存区被指定的版本覆盖,工作区被指定版本覆盖:
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
b16e8e14ccb603f5d1a9ae05aa69e771c1b2ee41 (HEAD -> master) third edit
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git reset --hard ce0fdd067f536c
HEAD is now at ce0fdd0 second edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git log --pretty=oneline
ce0fdd067f536cf5d2d1f76de1bd09d184258c49 (HEAD -> master) second edit
39d4917a3cb68596d2e6ff2173c0bf985d379399 first edit
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
nothing to commit, working tree clean
带文件参数的没有--soft
,--hard
只有--mixed
,表示HEAD不动,HEAD覆盖暂存区:
git reset <文件名>或者git reset --mixed <文件名>
(这种只对本地分支有效,对远程分支无效。也就是已经push到远程仓库的commit不允许reset)
修改比较
git diff HEAD -- <文件>
使用git diff HEAD -- <文件>
可以查看工作区和HEAD里最新版的不同之处
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git diff HEAD -- test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git diff HEAD -- test.txt
diff --git a/test.txt b/test.txt
index 2267ac8..f092ba5 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1,3 @@
first edit
second edit
-third edit
\ No newline at end of file
+third edit + fourth edit
\ No newline at end of file
删除文件
有时候误删rm <file>
了一个文件,需要找回时,使用git restore <文件>
从暂存区恢复
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ rm test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git restore test.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ ll
total 1
-rw-r--r-- 1 Qsky8 197609 35 4月 29 23:19 test.txt
有时候删除rm <file>
了一个文件,可以通过git rm <file>
从暂存区中删除文件,然后提交至HEAD
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ rm ti.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: ti.txt
no changes added to commit (use "git add" and/or "git commit -a")
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git rm ti.txt
rm 'ti.tQsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: ti.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git commit -m "delete ti.txt"
[master f981959] “delete ti.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 ti.txt
Qsky8@Nebula MINGW64 /d/Users/Qsky8/Desktop/git (master)
$ git status
On branch master
nothing to commit, working tree clean
留言