一文实现玩转Git(新人必看)
Git简介
Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git 是 Linus Torvalds 【Linux之父】为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。
- 集中式:版本库式集中放在中央服务器的。需要进行的时候,先从中央服务器中获得最新的版本,然后进行自己的工作,完成后,在把自己修改后的内容推送给中央服务器。因此最大的缺点是没有网络是不行的,并且中央服务器如果出了问题整个系统就瘫痪了。
- 分布式:没有中央服务器,每个机器上都有完整的版本库,多人协作只需要将自己的修改推送给其他人即可。因此一个人机器出问题只需要从别的机器上拷贝一份即可。
Git的windows安装
可以直接在官网下载:https://git-scm.com/download
但是官网速度可能很慢,可以换一个源:https://npm.taobao.org/mirrors/git-for-windows/
这个源向下滑动找到最新版本,然后点进去,选择符合自己机器和系统的版本下载即可。
安装过程就保持默认就行。
安装完成后,在开始菜单找到Git Bash,点击运行成功就说明下载完成;
安装完成后,设置一下自己的id和email:
$ git config --global user.name "your id"
$ git config --global user.email "your mail"
创建版本库
版本库就是一个目录,这个目录里的所有文件都可以被git管理,每个文件的修改、删除等git都可以追踪,从而任何时刻可以追踪修改历史并可以还原。
创建版本库的步骤:
-
创建一个新目录:
$ mkdir test --创建目录 $ cd test --进入该目录
-
将这个目录变为可以被git管理的仓库:
$git init --初始化为版本库
创建完成后,用 ls -ah
查看该目录内容,可以看到有 .git/
,说明创建成功了,git文件是帮助版本管理的。
本地仓库各种玩法
将文件添加到仓库
在test目录下创建一个txt文件并添加至仓库:
在此处我用vi创建了一个first.txt的文件,内容如下:
This is my first time using Git!
I believe in becoming a Master Git!
保存过后,下面是将其添加至本地仓库:
-
使用
git add <filename>
命令,将文件添加至暂存区:$ git add first.txt
-
使用
git commit -m <message>
命令,将暂存区的文件提交至仓库:$ git commit -m "I commit my first.txt. That's a test."
tips:可以向暂存区中放置多个文件,最后一次性commit即可
修改文件
修改first.txt
的内容,添加一行内容。
用git status
查看当前仓库状态:
$ 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: first.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到,git status
结果说明,有文件被修改但是并没有被commit。
通过git diff <filename>
可以知道哪些内容被修改了:
$ git diff first.txt
warning: LF will be replaced by CRLF in first.txt.
The file will have its original line endings in your working directory
diff --git a/first.txt b/first.txt
index 00bce21..234610e 100644
--- a/first.txt
+++ b/first.txt
@@ -1,2 +1,3 @@
This is my first time using Git!
I believe in becoming a Master Git!
+Add a line.
和上面步骤一样,通过 git add
和 git commit
将文件修改提交至仓库,然后git status
查看就会发现仓库目前无修改等内容。
总的流程如下:
版本回退
在git中,可以通过git log
查看版本控制系统的历史记录,显示顺序是由最近到最远提交:
$ git log
commit d645642c32fd9272ed2d14d0369c60cefb2dab2b (HEAD -> master)
Author: XXXX <XX@mymail.com>
Date: Thu Sep 17 11:29:42 2020 +0800
I change first.txt.
commit 8925d8e75e0ae3f6b2fae3fb11cf3861f67edf01
Author: XXXX <XX@mymail.com>
Date: Thu Sep 17 11:01:27 2020 +0800
I commit my first.txt. That's a test.
如果因为某种原因需要回到之前的某个版本,该怎么做?
采用git reset --hard commit_id
即可返回某个步骤 【HEAD^可以表示上一个版本】
$ git reset --hard HEAD^
HEAD is now at 8925d8e I commit my first.txt. That's a test.
$ cat first.txt
This is my first time using Git!
I believe in becoming a Master Git!
可以看到通过该方法就回到了之前的提交版本,此处的HEAD^可以用 git log中的 id 代替
回到之前的修改后,还可以再回到之前的版本吗?
只要知道每个版本的ID就可以回到任意版本,虽然回到之前版本后使用git log
将看不到之后的版本号,但是通过git reflog
可以看到每一次提交的版本号,因此找到对应的版本号即可回到任意版本。
$ git reflog
8925d8e (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
d645642 HEAD@{1}: commit: I change first.txt.
8925d8e (HEAD -> master) HEAD@{2}: commit (initial): I commit my first.txt. That's a test.
可以看到之前的版本id是d645642,因此使用git reset恢复:
$ git reset --hard d645642
HEAD is now at d645642 I change first.txt.
$ cat first.txt
This is my first time using Git!
I believe in becoming a Master Git!
Add a line.
因此通过commit_id便可以通过git reset回到任意版本!
管理修改
理解一下Git管理的是修改而不是文件:
先对文件进行修改然后git add
,然后再修改文件,然后提交:
对first.txt进行了修改:
$ cat first.txt
This is my first time using Git!
I believe in becoming a Master Git!
Add a line.
I change this file.
然后 git add first.txt
,将其加入暂存区
然后再次对first.txt进行了修改,然后git commit
,可以看到提交成功。
但是此时的git status
状态显示first.txt有修改却没有提交,这说明第二次的修改实际上并未提交到仓库上去,说明了Git管理的是修改而不是文件。
同时,通过git checkout --filename
可以丢弃在工作区的修改:
first.txt的第二个修改还没有提交,虽然文件保存过了,但是可以通过 git checkout
丢弃这次修改,然后会看到文件回到了上次commit或者add的状态。
删除文件
在本地执行 rm
就可以将文件删除,但是仓库里保存的信息仍然有这个文件。
$ rm first.txt
通过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: first.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到该修改还没有提交至仓库。
如果确实希望删除该文件,则将该修改进行提交即可,即执行’git commit -m “somethings” ’
如果不希望删除,则恢复这个操作即可, 通过 git checkout -- first.txt
或者通过 版本回退即可。
远程仓库玩法
预先配置
首先创建一个GitHub账号【全球最大同性交友网站(*^_^*)】,由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,因此需要设置SSH。
- 在用户主目录下,看看有没有.ssh目录,如果有并且这个目录下有
id_rsa
和id_rsa.pub
这两个文件就可直接跳到下一步,否则的话,需要创建一个SSH Key ,ssh-keygen -t rsa -C "youremail@example.com"
,一路回车默认即可,然后就可以找到.ssh目录,并且有id_rsa
和id_rsa.pub
两个文件,其中,id_rsa
是私钥,id_rsa.pub
是公钥 - 登陆自己的Github,然后点击自己头像,选择
setting
,点击SSH and GPG keys
,添加一个新的SSH keys,将id_rsa.pub
的内容粘贴到Key中即可
至此,完成了本地仓库和远程仓库的SSH配置。
建立远程仓库
希望的目标:在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步。
在Github建立仓库:
登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库。
可以将仓库名字命名为learn-git,之后绑定要用到。
本地与远程仓库同步
然后将本地仓库与远程仓库进行关联:
git remote add origin git@github.com:name/learn-git
注意将name替换成自己的name,后面为Github的仓库名。
默认远程库的名字就是origin
,当然可以改成别的。
通过 git push -u origin master
将本地内容推送到远程库中。
如果推送失败:
出现git提交远程报错[rejected] master -> master (fetch first),则 输入git pull --rebase origin master
,之后再 git push
即可。
$ git push -u origin master
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 4 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 813 bytes | 203.00 KiB/s, done.
Total 9 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), done.
To github.com:coding-dingjq/learn-git
175f009..954125e master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
然后查看Github的learn-git仓库,可以看到本地的first.txt已经被推送至仓库。
如何从Github远程仓库同步信息到本地呢?
git clone
!
git clone git@github.com:name/learn-git
就可以实现从远程库克隆文件到本地仓库了。
分支管理
Git通过分支管理来进行版本控制,每个分支代表着一条时间线,master分支就是主分支,也可以创建不同的分支,最后进行提交与合并即可。
分支创建与切换
创建分支:git branch name
切换分支:git checkout name
或者 git switch name
git checkout -b name
或者 git switch -c name
可以创建并切换分支。
通过git branch
可以查看分支信息。
试一下新建一个分支并在该分支上做修改:
新建了一个分支并修改了first.txt的内容,然后提交该修改。
$ git add first.txt
$ git commit -m "create a new branch and change first.txt on the new branch"
[dev fcf0b4d] create a new branch and change first.txt on the new branch
1 file changed, 2 insertions(+)
切换回master分支查看内容:
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git branch
dev
* master
$ cat first.txt
This is my first time using Git!
I believe in becoming a Master Git!
Add a line.
I change this file.
会发现,first.txt并没有被修改。
合并分支
实际上,当前分支的关系如下图所示:
因此,要想同步dev分支上的修改到master分支,需要进行分支合并。
通过git merge dev
将dev分支合并至当前分支,查看first.txt内容会看到在dev上的修改已经生效于master。
此时实际上dev和master分支已经一致了, 可以通过git branch -d dev
删除dev分支。
解决冲突
在不同分支上进行修改,合并时可能会引发冲突,例如都对first.txt
的第一行进行了修改,合并时就会产生冲突,没办法合并。对于这种情况,Git的方法是先手动解决冲突,再合并。
动手试一下:
在dev和master分支上都在first.txt的同一行添加不同内容并commit:
在master分支上修改:
在dev分支上修改:
切换到master分支时,可以看到有提示:
指当前master分支领先远程仓库两次提交,可以用git push同步。
进行git merge
合并:
$ git merge dev
Auto-merging first.txt
CONFLICT (content): Merge conflict in first.txt
Automatic merge failed; fix conflicts and then commit the result.
可以看到有冲突,
查看此时的first.txt
内容:
可以看到在有冲突的地方进行了部分修改。
Git用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容
在此处修改后在提交即可,也就是手动处理冲突再提交的思想。也就是当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。解决冲突就是把Git合并失败的文件自己手动编辑,再提交。
用带参数的git log
也可以看到分支的合并情况:
Git内容非常多,并且细节也颇为繁琐,不过掌握以上内容便可以玩转大部分Git内容,遇到更多其他需求可以自行查阅资料即可!