Git使用教程

Git是目前世界上最先进的分布式版本控制系统。

工作原理 / 流程:
在这里插入图片描述

  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库

Git 的安装、配置就不说了,直接说如何操作。

一,创建版本库
sulei32@ZBMAC-C02D42W8M ~ % cd Project 
sulei32@ZBMAC-C02D42W8M Project % mkdir test
sulei32@ZBMAC-C02D42W8M Project % cd test
sulei32@ZBMAC-C02D42W8M test % pwd
/Users/sulei32/Project/test

首先用终端创建了一个test目录,然后通过命令 git init 把这个目录变成git可以管理的仓库。

sulei32@ZBMAC-C02D42W8M test % git init
Initialized empty Git repository in /Users/sulei32/Project/test/.git/

这时候test目录下会多了一个.git的隐藏目录,这个目录是Git来跟踪管理版本的,没事千万不要手动乱改这个目录里面的文件,否则,会把 git 仓库给破坏了。

sulei32@ZBMAC-C02D42W8M test % touch readme.txt
sulei32@ZBMAC-C02D42W8M test % ls
readme.txt
sulei32@ZBMAC-C02D42W8M test % git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	readme.txt

nothing added to commit but untracked files present (use "git add" to track)

在 test 目录下创建一个 readme.txt 文件,然后输入 git status 命令,命令告诉我们 readme.txt 是一个Untracked(未追踪)的文件,提醒我们用 git add 命令把文件暂存区。

sulei32@ZBMAC-C02D42W8M test % git add readme.txt 
sulei32@ZBMAC-C02D42W8M test % git commit -m "提交readme.txt"
[master (root-commit) 752c1d2] 提交readme.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 readme.txt
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
  1. 用 git add 命令把 readme.txt 文件添加到暂存区。
  2. 用 git commit 命令把 readme.txt 文件提交到仓库。
  3. 用 git status 查看,发现没有需要提交的文件了。

下面我们来修改 readme.txt 文件的内容,输入一行11111,继续使用 git status 来查看下结果

sulei32@ZBMAC-C02D42W8M test % 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")

上面的结果告诉我们,readme.txt 文件已被 modified(修改),但是未被提交。我们可以使用 git add 命令把文件的修改添加到暂存区;也可以使用 git restore 命令 discard(丢弃)本次的修改。我们先执行 git add 命令,然后在使用 git status 来查看结果

sulei32@ZBMAC-C02D42W8M test % git add . 
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   readme.txt

上面结果告诉我们,本次对 readme.txt 文件的修改已经在暂存区了,可以使用 git commit 命令提交到仓库;也可以使用 git restore --staged 命令 unstage(从暂存区中移除)本次的修改。我们先执行 git commit 命令,然后在使用 git status 来查看结果,搞定。

sulei32@ZBMAC-C02D42W8M test % git commit -m "提交11111" 
[master 0daf0ad] 提交11111
 1 file changed, 1 insertion(+)
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
二,版本回退:

我们先对 readme.txt 文件进行两次修改,分别增加两行22222和333333。

sulei32@ZBMAC-C02D42W8M test % open readme.txt
sulei32@ZBMAC-C02D42W8M test % git add .
sulei32@ZBMAC-C02D42W8M test % git commit -m "22222"
[master 10e281f] 22222
 1 file changed, 2 insertions(+), 1 deletion(-)
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % open readme.txt      
sulei32@ZBMAC-C02D42W8M test % git add .            
sulei32@ZBMAC-C02D42W8M test % git commit -m "333333"
[master af5b641] 333333
 1 file changed, 2 insertions(+), 1 deletion(-)
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
33333

好了,现在我们已经对 readme.txt 文件做了三次修改了,那么我现在想查看下历史记录,如何查呢?我们可以使用 git log 命令。

sulei32@ZBMAC-C02D42W8M test % git log
commit af5b641fa767d1cc7d61554a5847bf5873f771e8 (HEAD -> master)
Author: sulei32 <sulei32@jd.com>
Date:   Thu Mar 11 18:43:18 2021 +0800

    333333

commit 10e281f6a0050c9fec649849d73ac85956912947
Author: sulei32 <sulei32@jd.com>
Date:   Thu Mar 11 18:42:42 2021 +0800

    22222

commit 0daf0ad5bc634278607ffd0bf0b05a66734aa191
Author: sulei32 <sulei32@jd.com>
Date:   Thu Mar 11 18:09:16 2021 +0800

    提交11111

commit 752c1d20a3254e375b7e0a6b91b3509115d0a0ef
Author: sulei32 <sulei32@jd.com>
Date:   Thu Mar 11 17:48:17 2021 +0800

    提交readme.txt
    

git log 命令是从最近到最远的显示日志,日志信息分别为:每次提交的版本号、提交人、提交时间、提交的日志信息。如果现在我们想进行版本回退操作,我要回退到上个版本,有两种方法:第一种,使用 git reset --hard HEAD^ 命令, 那么如果要回退到上上个版本只需把HEAD^ 改成 HEAD^^,如果要回退到前100个版本的话,我们可以使用更简便命令 git reset --hard HEAD~100 。第二种,使用 git reset --hard 版本号 命令,版本号可以使用 git reflog 命令来获取。我们分别来试下这两种方法:

sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
33333
sulei32@ZBMAC-C02D42W8M test % git reset --hard HEAD^
HEAD is now at 10e281f 22222
sulei32@ZBMAC-C02D42W8M test % more readme.txt       
11111
22222
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % git reflog
3ff090b (HEAD -> master) HEAD@{0}: commit: 33333
10e281f HEAD@{1}: reset: moving to HEAD^
af5b641 HEAD@{2}: commit: 333333
10e281f HEAD@{3}: commit: 22222
0daf0ad HEAD@{4}: commit: 提交11111
752c1d2 HEAD@{5}: commit (initial): 提交readme.txt
sulei32@ZBMAC-C02D42W8M test % git reset --hard 10e281f
HEAD is now at 10e281f 22222
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
sulei32@ZBMAC-C02D42W8M test % 

这时还有个问题,如果我已经回退到22222的版本了,但是现在我想再次回退到33333版本,那怎么办呢?我们可以用上面的第二种办法解决这个问题。

sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
sulei32@ZBMAC-C02D42W8M test % git reflog
10e281f (HEAD -> master) HEAD@{0}: reset: moving to 10e281f
3ff090b HEAD@{1}: commit: 33333
10e281f (HEAD -> master) HEAD@{2}: reset: moving to HEAD^
af5b641 HEAD@{3}: commit: 333333
10e281f (HEAD -> master) HEAD@{4}: commit: 22222
0daf0ad HEAD@{5}: commit: 提交11111
752c1d2 HEAD@{6}: commit (initial): 提交readme.txt
sulei32@ZBMAC-C02D42W8M test % git reset --hard 3ff090b
HEAD is now at 3ff090b 33333
sulei32@ZBMAC-C02D42W8M test % more readme.txt         
11111
22222
33333
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
三,撤销修改

撤销修改操作分为三种情况:1,修改没有 add ;2,修改已经 add,但是没有 commit;3,修改已经 commit;4,修改已经被 push 到远程仓库。比如我在 readme.txt 文件里加了一行44444,现在我想撤销本次修改,针对上面的四种情况,我们分别处理。
第一种情况,使用 git restore 命令。

sulei32@ZBMAC-C02D42W8M test % 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")
sulei32@ZBMAC-C02D42W8M test % git restore .
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
33333

第二种情况,分两步:1,使用 git restore --staged 命令,把已经 add 的修改变成没有add;2,用第一种方法撤销修改。

sulei32@ZBMAC-C02D42W8M test % git add .
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   readme.txt

sulei32@ZBMAC-C02D42W8M test % git restore --staged .
sulei32@ZBMAC-C02D42W8M test % 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")

第三种情况,使用上一节的版本回退方法。
第四种情况,放到下一节讲,我们现在还没有远程仓库。

四,远程仓库

上面说的都是本地仓库(Repository),本节开始学习远程仓库(Remote)并且把Repository和Remote进行同步。现在的情景是:我们已经在本地创建了一个Git仓库,又想在github创建一个Git仓库,并且希望这两个仓库进行远程同步,这样github的仓库可以作为备份,又可以其他人通过该仓库来协作。

1,创建远程仓库

首先,登录github上,然后在右上角找到“create a new repo”创建一个新的仓库,然后在Repository name 填入test,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库。
在这里插入图片描述在这里插入图片描述
目前,在GitHub上的这个test仓库还是空的,GitHub告诉我们:

  1. 用命令行创建新的本地仓库,然后把本地仓库的内容推送(push)到远程仓库。
  2. 如果已经存在本地仓库,可以直接把本地仓库的内容推送(push)到远程仓库。
  3. 可以从其他远程仓库导入(import)代码。

我们已经有本地仓库了,所以使用第二种方法。

sulei32@ZBMAC-C02D42W8M test % git remote add origin https://github.com/sulei007/test.git
sulei32@ZBMAC-C02D42W8M test % git push -u origin master
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (12/12), 866 bytes | 866.00 KiB/s, done.
Total 12 (delta 0), reused 0 (delta 0)
To https://github.com/sulei007/test.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
sulei32@ZBMAC-C02D42W8M test % 

把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了 –u参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
在这里插入图片描述
现在我们往 readme.txt 里添加一行44444,git add 和 git commit 后,使用 git status 命令查看结果:

sulei32@ZBMAC-C02D42W8M test % git add .
sulei32@ZBMAC-C02D42W8M test % git commit -m "提交44444"
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

请注意,git commit 命令后,git status 的提示信息跟前面几节只有本地仓库的时候不一样了,git 提示我们,本地分支的内容领先远程分支,建议我们用 git push 命令把本地的修改提交到远程仓库。

sulei32@ZBMAC-C02D42W8M test % git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 258 bytes | 258.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/sulei007/test.git
   53aa659..1ddd36d  master -> master
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
2,如何从远程库克隆?

我们在Project下,新建一个test2的空目录,然后在test2目录下,使用 git clone 命令。

sulei32@ZBMAC-C02D42W8M Project % mkdir test2
sulei32@ZBMAC-C02D42W8M Project % ls
dy-pos-android	test		test2
sulei32@ZBMAC-C02D42W8M Project % cd test2
sulei32@ZBMAC-C02D42W8M test2 % ls
sulei32@ZBMAC-C02D42W8M test2 % git clone https://github.com/sulei007/test.git
Cloning into 'test'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 15 (delta 0), reused 15 (delta 0), pack-reused 0
Unpacking objects: 100% (15/15), done.
sulei32@ZBMAC-C02D42W8M test2 % ls
test

可以看到,远程仓库的test目录,已经被克隆到本地的test2目录下了。

五、操作分支

按照上面的操作,我们创建的仓库只有一个分支 master 分支,也叫主分支,可以使用 git branch 命令查看本地分支,会列出所有的本地分支,当前分支前面会添加一个星号。我们如果要查看远程分支,可以使用 git branch -a 命令,远程分支带有 remotes/origin 前缀。

sulei32@ZBMAC-C02D42W8M test % git branch 
* master

下面,我们来创建dev本地分支,然后切换到dev本地分支上。可以使用 git checkout -b dev 命令,这条命令相当于如下两条命令: git branch dev 和 git checkout dev。

sulei32@ZBMAC-C02D42W8M test % git checkout -b dev
Switched to a new branch 'dev'
sulei32@ZBMAC-C02D42W8M test % git branch
* dev
  master
sulei32@ZBMAC-C02D42W8M test % git branch -a
* dev
  master
  remotes/origin/master

上面结果可以看到,dev是本地分支,我们需要把dev本地分支推送到远程仓库。

sulei32@ZBMAC-C02D42W8M test % git push -u origin dev   
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 259 bytes | 259.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: 
remote: Create a pull request for 'dev' on GitHub by visiting:
remote:      https://github.com/sulei007/test/pull/new/dev
remote: 
To https://github.com/sulei007/test.git
 * [new branch]      dev -> dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
sulei32@ZBMAC-C02D42W8M test % git branch -a
* dev
  master
  remotes/origin/dev
  remotes/origin/master

然后我们在 dev 分支下的 readme.txt 新增一行55555,然后 git add 、git commit 、git push 到远程 dev 分支,然后切换到 master 分支,我们发现 master 下的 readme.txt 文件没有55555这一行。

sulei32@ZBMAC-C02D42W8M test % git branch
* dev
  master
sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
33333
44444
55555
sulei32@ZBMAC-C02D42W8M test % git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
sulei32@ZBMAC-C02D42W8M test % more readme.txt    
11111
22222
33333
44444

现在我们可以把 dev 分支上的内容合并到 master 分支上了,在 master 分支上,使用 git merge dev 命令,可以看到在 master 分支下的 readme.txt 文件里也有55555这一行了,然后我们把修改 push 到远程仓库。

sulei32@ZBMAC-C02D42W8M test % git branch
  dev
 * master
sulei32@ZBMAC-C02D42W8M test % git merge dev
Updating 1ddd36d..0c5fe0b
Fast-forward
 readme.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
33333
44444
55555
sulei32@ZBMAC-C02D42W8M test % git push 
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/sulei007/test.git
   1ddd36d..0c5fe0b  master -> master

总结创建与合并分支命令如下:

  • 查看分支:git branch,git branch -a
  • 创建本地分支:git branch name
  • 切换本地分支:git checkout name
  • 创建+切换本地分支:git checkout –b name
  • 合并某本地分支到当前本地分支:git merge name
  • 删除本地分支:git branch –d name,只能删除非当前分支
  • 拉去远程分支到本地:git checkout -b xxxx(本地分支名称)yyyy(远程分支的名称)

在合并分支的时候,有可能会出现冲突,比如我们在 dev 分支上加了一行aaaaaa,提交;然后在 master 分支上也加了一行bbbbbb,当把 dev 分支合并到 master 分支上时,就会合并失败,提示有冲突(conflict)。

sulei32@ZBMAC-C02D42W8M test % git merge dev 
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
sulei32@ZBMAC-C02D42W8M test % more readme.txt 
11111
22222
33333
44444
55555
<<<<<<< HEAD
bbbbb
=======
aaaaa
>>>>>>> dev

Git 用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,其中<<<<<<< HEAD 是指 master 分支修改的内容,>>>>>>> dev 是指 dev 上修改的内容,我们可以修改下,然后提交。

sulei32@ZBMAC-C02D42W8M test % more readme.txt  
11111
22222
33333
44444
55555
bbbbb
aaaaa
sulei32@ZBMAC-C02D42W8M test % git add .
sulei32@ZBMAC-C02D42W8M test % git commit -m "merge冲突"
[master 0241f2b] merge冲突
sulei32@ZBMAC-C02D42W8M test % git push
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (9/9), 699 bytes | 699.00 KiB/s, done.
Total 9 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/sulei007/test.git
   0c5fe0b..0241f2b  master -> master

下面我们说下上一节课遗留的问题,我现在把 dev 分支合并到 master 分支上了,并且已经 push 到远程仓库了,但是现在我想撤销这次合并,master 分支上的 readme.txt 文件不要55555这一行了。分两步:1,在 master 本地分支上使用 git reset --hard HEAD^ 命令,回退到上个版本;2,使用 git push -f 命令强制提交,远程 master 分支的将强制更新到本地 reset 的版本。

sulei32@ZBMAC-C02D42W8M test % git reset --hard HEAD^
HEAD is now at 1ddd36d 提交44444     
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % git push  
To https://github.com/sulei007/test.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/sulei007/test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
sulei32@ZBMAC-C02D42W8M test % git push -f
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/sulei007/test.git
 + 0c5fe0b...1ddd36d master -> master (forced update)
sulei32@ZBMAC-C02D42W8M test % git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

上面结果可以看到,如果不加 -f 参数,git push 命令是会报错的,原因是本地分支的版本低于远程分支的版本。

六,修复bug

在开发中,会经常碰到bug,那么有了bug就需要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉。
比如在开发中接到一个 bug ,我们可以创建一个 fix 分支来修复它,但是,当前的 dev 分支上的工作还没有提交。

sulei32@ZBMAC-C02D42W8M test % git status
On branch dev
Your branch is up to date with 'origin/dev'.

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")
sulei32@ZBMAC-C02D42W8M test % git checkout master
error: Your local changes to the following files would be overwritten by checkout:
	readme.txt
Please commit your changes or stash them before you switch branches.
Aborting

这个时候我们 dev 分支上的开发工作还没有完成,我们并不想提交,但是修复 bug 肯定更为紧急,怎么办呢?看上面的提示信息,可以使用 git stash 命令,把当前的修改 ”缓存起来”,等修复完bug后继续工作。

sulei32@ZBMAC-C02D42W8M test % git stash
Saved working directory and index state WIP on dev: 0c5fe0b 提交55555
sulei32@ZBMAC-C02D42W8M test % git status
On branch dev
Your branch is up to date with 'origin/dev'.

nothing to commit, working tree clean
sulei32@ZBMAC-C02D42W8M test % git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'

上面结果显示,我们成功的切换到了 master 分支,那么我们就可以在 master 分支上新建一个 fix 分支,在 fix 分支里修复完bug,把 fix 分支合并到 master 分支上,然后删除 fix 分支,这样bug 就修复好了。我们再切换到 dev 分支,用 git stash list 命令来查看缓存列表,然后用 git stash pop 命令来取出缓存,该命令会从列表头部依次取出缓存,且在取出某条缓存的同时也会把这条缓存从列表中删除了。

sulei32@ZBMAC-C02D42W8M test % git stash list
stash@{0}: WIP on dev: 0c5fe0b 提交55555
sulei32@ZBMAC-C02D42W8M test % open readme.txt 
sulei32@ZBMAC-C02D42W8M test % git stash pop
On branch dev
Your branch is up to date with 'origin/dev'.

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")
Dropped refs/stash@{0} (515083e1a15171c2b23e689e1a334f3f9232e606)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值