1、git init 创建版本库
创建一个空目录
mkdir gitTest
$ cd gitTest
使用 git init 命令,把这个目录变成Git可以管理的仓库
PS D:\gitTest> git init
Initialized empty Git repository in D:/gitTest/.git/
2、git add 新增文件,并提交
新增一个文件 readme.txt
Git is a version control system.
Git is free software.
使用 git add 告诉Git,把文件添加到仓库
git add readme.txt
用命令git commit 告诉Git,把文件提交到仓库:-m 后面输入的是本次提交的说明
git commit -m "wrote a readme file"
3、git status 查看状态
修改readme.txt文件,改成如下内容:
Git is a distributed version control system.
Git is free software.
运行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")
4、git diff 查看不同
虽然Git告诉我们readme.txt 被修改了,要用git diff 这个命令看看修改了什么:
git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system. 删除了
+Git is a distributed version control system. 新增的
Git is free software. 未修改
修改后,然后再提交 也是使用 git add ,之后看下状态
git add readme.txt
git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
告诉我们,将要被提交的修改包括readme.txt ,下一步,就可以放心地提交了:
git commit -m "add distributed"
[master c2add21] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)
提交后,再看下状态
git status
On branch master
nothing to commit, working tree clean
5、git log 查看提交历史
再次修改文件为
Git is a distributed version control system.
Git is free software distributed under the GPL.
修改好了提交
git add readme.txt
git commit -m "append GPL"
[master 2bb4911]] append GPL
1 file changed, 1 insertion(+), 1 deletion(-)
我们已经修改了三次,可以用 git log 命令查询
git log
commit 2bb4911c23a25048f3c4c19d0b627ac4c06abb00 (HEAD -> master)
Author: tangcy <3247306211@qq.com>
Date: Fri Apr 22 15:50:34 2022 +0800
append GPL
commit c2add212bfe48e658f724521ba541b243b5ab0cc
Author: tangcy <3247306211@qq.com>
Date: Fri Apr 22 15:48:07 2022 +0800
add distributed
commit 9ea1dd80ce8540b1a248031ddeafd6fd2cb86d32
Author: tangcy <3247306211@qq.com>
Date: Fri Apr 22 15:31:54 2022 +0800
wrote a readme file
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline 参数:
git log --pretty=oneline
2bb4911c23a25048f3c4c19d0b627ac4c06abb00 (HEAD -> master) appen
c2add212bfe48e658f724521ba541b243b5ab0cc add distributed
9ea1dd80ce8540b1a248031ddeafd6fd2cb86d32 wrote a readme file
6、git reset 版本回退
准备把readme.txt 回退到上一个版本,也就是add distributed 的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD 表示当前版本,也就是最新的提交1094adb... (注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^ ,上上一个版本就是HEAD^^ ,当然往上100个版本写100个^ 比较容易数不过来,所以写成HEAD~100 。
现在,我们要把当前版本append GPL 回退到上一个版本add distributed ,就可以使用git reset 命令:
git reset --hard HEAD^
HEAD is now at c2add21 add distributed
看看readme.txt 的内容是不是版本add distributed :
cat readme.txt
Git is a distributed version control system.
Git is free software.
用git log 再看看现在版本库的状态:
PS D:\gitTest> git log
commit c2add212bfe48e658f724521ba541b243b5ab0cc (HEAD -> master)
Author: tangcy <3247306211@qq.com>
Date: Fri Apr 22 15:48:07 2022 +0800
add distributed
commit 9ea1dd80ce8540b1a248031ddeafd6fd2cb86d32
Author: tangcy <3247306211@qq.com>
Date: Fri Apr 22 15:31:54 2022 +0800
wrote a readme file
7、git reflog 查看命令历史
最新的那个版本append GPL 已经看不到了,Git提供了一个命令git reflog 用来记录你的每一次命令:
git reflog
2bb4911 (HEAD -> master) HEAD@{2}: commit: append GPL
c2add21 HEAD@{3}: commit: add distributed
9ea1dd8 HEAD@{4}: commit: wrote a readme file
发现,append GPL 操作的commit id 为 2bb4911 ,指定版本回退,
git reset --hard 2bb4911
HEAD is now at 2bb4911 append GPL
再查看文件,发现已经改回来了
cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
8、工作区和暂存区
工作区
就是你在电脑里能看到的目录,比如我的gitTest 文件夹就是一个工作区
版本库
工作区有一个隐藏目录.git ,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master ,以及指向master 的一个指针叫HEAD 。
先对readme.txt 做个修改,比如加上一行内容:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
然后,在工作区新增一个LICENSE 文本文件(内容随便写)。
先用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
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE
no changes added to commit (use "git add" and/or "git commit -a")
Git非常清楚地告诉我们,readme.txt 被修改了,而LICENSE 还从来没有被添加过,所以它的状态是Untracked 。
现在,使用两次命令git add ,把readme.txt 和LICENSE 都添加后,用git status 再查看一下:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: LICENSE
modified: readme.txt
现在,暂存区的状态就变成这样了:
所以,git add 命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit 就可以一次性把暂存区的所有修改提交到分支。
$ git commit -m "understand how stage works"
[master e43a48b] understand how stage works
2 files changed, 2 insertions(+)
create mode 100644 LICENSE
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:
$ git status
On branch master
nothing to commit, working tree clean
现在版本库变成了这样,暂存区就没有任何内容了:
9、git restore 撤销修改
-
修改了,未 add 修改后,先查看一下状态 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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
Git会告诉你,git restore file 可以丢弃工作区的修改: git restore readme.txt
-
修改了,且 add 了 修改并add之后,先查看一下状态 git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
Git同样告诉我们,用命令git restore --staged 可以把暂存区的修改撤销掉(unstage),重新放回工作区: git restore --staged readme.txt
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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
丢弃工作区的修改 git restore readme.txt
10、git rm 删除文件
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt 到Git并且提交:
git add test.txt
git commit -m "add test.txt"
[master b84166e] add test.txt
1 file changed, 1 insertion(+)
create mode 100644 test.txt
一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm 命令删了:
rm test.txt
这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status 命令会立刻告诉你哪些文件被删除了:
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")
-
确实要从版本库中删除该文件,那就用命令git rm 删掉,并且git commit : git rm test.txt
rm 'test.txt'
git commit -m "remove test.txt"
[master 1c50083] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
-
误删了,需要还原 git restore test.txt
11、git clone 从远程库中克隆
现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。
首先,登陆GitHub或者Gitee,创建一个新的仓库,名字叫gitTest :
git clone https://gitee.com/datang_yun/gitTest.git
12、分支管理
12.1 git checkout -b 创建并切换分支
首先,我们创建dev 分支,然后切换到dev 分支:
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout 命令加上-b 参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
12.2 git branch 查看分支
然后,用git branch 命令查看当前分支:
$ git branch
* dev
master
git branch 命令会列出所有分支,当前分支前面会标一个* 号。
然后,我们就可以在dev 分支上正常提交,比如对readme.txt 做个修改,加上一行:
Creating a new branch is quick.
然后提交:
$ git add readme.txt
$ git commit -m "branch test"
[dev b17d20e] branch test
1 file changed, 1 insertion(+)
现在,dev 分支的工作完成,我们就可以切换回master 分支:
$ git checkout master
Switched to branch 'master'
切换回master 分支后,再查看一个readme.txt 文件,刚才添加的内容不见了!因为那个提交是在dev 分支上,而master 分支此刻的提交点并没有变:
12.3 git merge dev 合并分支
现在,我们把dev 分支的工作成果合并到master 分支上:
$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
git merge 命令用于合并指定分支到当前分支。合并后,再查看readme.txt 的内容,就可以看到,和dev 分支的最新提交是完全一样的。
注意到上面的Fast-forward 信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master 指向dev 的当前提交,所以合并速度非常快。
当然,也不是每次合并都能Fast-forward ,我们后面会讲其他方式的合并。
12.4 git branch -d 删除分支
合并完成后,就可以放心地删除dev 分支了:
$ git branch -d dev
Deleted branch dev (was b17d20e).
删除后,查看branch ,就只剩下master 分支了:
$ git branch
* master
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master 分支上工作效果是一样的,但过程更安全。
12.5 解决冲突
当要合并的两个分支都有新的提交时,这时候会有冲突
我们在 dev 分支 修改readme.txt 最后一行,改为:
Creating a new branch is quick AND simple.
在dev 分支上提交:
git add readme.txt
git commit -m "AND simple"
[dev 69646ae] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)
切换到master 分支:
git checkout master
在master 分支上把readme.txt 文件的最后一行改为:
Creating a new branch is quick & simple.
在master 分支上提交:
git add readme.txt
git commit -m "& simple"
[master f741101] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)
这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:
git merge dev
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
查看 readme.txt 文件
Git is a distributed version control system.
Git is free software distributed under the GPL.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> dev
编辑冲突,手动改为
Creating a new branch is quick and simple.
提交
$ git add readme.txt
$ git commit -m "conflict fixed"
[master f741101] conflict fixed
用带参数的git log 也可以看到分支的合并情况:
PS D:\gitTest> git log --graph --pretty=oneline --abbrev-commit
* d915136 (HEAD -> master) conflict fixed
|\
| * 69646ae (dev) AND simple
* | f741101 & simple
|/
* 5b7b6a4 branch test
13、git stash 保存未完成的分支
当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101 来修复它,但是,等等,当前正在dev 上进行的工作还没有提交,并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?
Git还提供了一个stash 功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge
$ git status
On branch dev
nothing to commit, working tree clean
工作区是干净的,刚才的工作现场存到哪去了?用git stash list 命令看看:
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
-
用git stash apply 恢复,但是恢复后,stash内容并不删除,你需要用git stash drop 来删除; stash 了多次,指定恢复哪个 可以使用
$ git stash apply stash@{0}
-
用git stash pop ,恢复的同时把stash内容也删了 $ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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
Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)
14、git cherry-pick 合并某个提交到当前分支
可能存在这种情况,我们在master 上修复了bug,提交了两个步骤commit1 和 commit2,可能 commit1 做的修改,在dev上也要同步,但不需要同步commit2,这时候,可以使用 cherry-pick 命令,让我们能复制一个特定的提交到当前分支:
$ git branch
* dev
master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)
比如,master分支和dev分支,有一个readme.txt文件,文件内容分别为 master提交和dev提交
对比dev和master的区别,知道那次的提交记录为 97d5fe40 再使用 git cherry-pick 97d5fe40 命令,合并这次的提交
|