git 总结终结篇
关于git,之前总是遇到什么问题然后做了一个简单总结。今天决定来一个系统的总结,加深一下自己对git的理解。
1、安装git
这个没有什么好说的,直接去官网下载安装就可以了。安装之后进行配置:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
- config:配置 --global:全局 表示这个电脑上的所有仓库都会使用这个配置。
2、创建版本库
执行git init
,就可以了:
$ git init
Initialized empty Git repository in C:/Users/刘欢/Desktop/gittest/.git/
- Initialized empty Git repository就是告诉我们已经在本地初始化了一个本地仓库。initialzed---init
看到.git
目录,就说明初始化成功。
2.1、git add .
添加文件到暂存区
我们新建一个txt文件来测试,注意不要使用Windows自带的记事本,因为它保存UTF-8编码文件时,在开头添加了十六进制的字符,可能会遇到问题。这里用sublime来写的txt文件。
值得注意的是,应该建到我们初始化git的这个目录,有点废话这句。
txt内容:
git is a version control system
magicliu is a handsome man
然后执行git add magicliu.txt将文件提交到暂存区。
暂存区这个东西是git借鉴了svn的有点而存在的,因为我们可能一次修改了很多文件,然后一个一个提交备注会十分麻烦,我们可以将一天修改的都提交到暂存区,然后到下班的时候将暂存区的东西以一天为时间点,
git commit -m "备注信息"
提交到仓库。就会方便很多。也就是说我们可以多次add,然后执行一个commit.
2.2、git commit -m "备注信息"
将文件从暂存区提交到本地仓库
$ git commit -m "a new fil"
[master (root-commit) 36cd309] a new file
1 file changed, 2 insertions(+)
create mode 100644 magicliu.txt
这样就从暂存区提交到了本地仓库。
3、修改文件管理
现在修改了maciliu.txt
:
git is a version control system
magicliu is a handsome cool man
运行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: magicliu.txt
no changes added to commit (use "git add" and/or "git commit -a")
- modified:改正的,修正的;提示我们修改了
magicliu.txt
。
那么怎么看修改了什么呢?git diff
就可以了,顾名思义diff就是difference的意思。
$ git diff
diff --git a/magicliu.txt b/magicliu.txt
index 274ea95..4d53871 100644
--- a/magicliu.txt
+++ b/magicliu.txt
@@ -1,2 +1,2 @@
git is a version control system
-magicliu is a handsome man
\ No newline at end of file
+magicliu is a handsome cool man
\ No newline at end of file
这样就可以看到magicliu is a handsome man被修改为了magicliu is a handsome cool man。
git add magicliu.txt
,之后git status
查看一下状态:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: magicliu.txt
可以看到修改的文件为maciliu.txt,还提示了git reset HEAD
去返回上一阶段。然后就是git commit 提交代码:
$ git commit -m "add cool"
[master c73247b] add cool
1 file changed, 1 insertion(+), 1 deletion(-)
现在在用git status
查看一下状态:
$ git status
On branch master
nothing to commit, working tree clean
可以看到:没有东西需要提交,工作目录是干净的。
3.1、版本回退
现在我们想看一下提交日志,用git log
查看:
$ git log
commit c73247bfb445ea48eb3cc634e9fa3cf38da3c363 (HEAD -> master)
Author: liuhuan <18512104146@163.com>
Date: Wed Dec 20 23:09:31 2017 +0800
add cool
commit 36cd3093230a020ee381bb59e7596096868e1ab7
Author: liuhuan <18512104146@163.com>
Date: Tue Dec 19 23:05:53 2017 +0800
a new file
这样,很清楚的看到了从最近开始的所以提交记录。
- commit 后面的一大串数字,就是我们提交的commit ID即我们提交的版本号,是十六进制来表示的。
现在我们想退回上个版本怎么办呢?
在git中有一个指针
HEAD
指向当前版本,我们退回的时候只需要修改HEAD
指向某个版本就可以了:上个版本就是HEAD^
,上两个版本就是HEAD^^
,100个版本就是HEAD~100
;当然也可以git reset --haed
+commit ID来退回某个版本,输入ID的时候只需要输入前几位就可以了,没必要全部输入
值得一提的是:回到指定ID的时候是不用加HEAD的
现在输入git reset --hard HEAD^
来退回上个版本:
$ git reset --hard HEAD^
HEAD is now at 36cd309 a new file
可以看到,我们已经回到了第一次提交新文件的版本,可以回去看下txt:
git is a version control system
magicliu is a handsome man
果然,cool不在了。
我们再用git log
看一下日志:
$ git log
commit 36cd3093230a020ee381bb59e7596096868e1ab7 (HEAD -> master)
Author: liuhuan <18512104146@163.com>
Date: Tue Dec 19 23:05:53 2017 +0800
a new file
可以看到add cool这个日志也不存在了。
现在,我们发现退回版本错误了。想回到之前的版本怎么做呢?
只需要去网上翻到之前的日志,找到那个commit ID。然后git reset --hard
+commit ID退回那个版本就行了:
$ git reset --hard c73247bfb445
HEAD is now at c73247b add cool
可以看到,已经回到了cool那个版本,可以看下txt文件:
git is a version control system
magicliu is a handsome cool man
cool~又回来了!
3.2、版本回退
比如,我们修改了一些东西。发现是没有 ssh地址.png$ 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: liu.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到代码提交:modified liu.txt即这个文件被修改;git add file去提交到缓存区;git checkout -- file去discard丢弃,放弃工作区的修改。
值得一提的是哪怕你提交修改到了缓存区,但没有提交到版本库代码依然是可以的。
3.3、删除文件
我们在文件夹中新建一个test.txt文件,然后git add-->git commit提交到版本库。
我们删除文件时,可以直接在文件夹中删除,或者在git 中用 rm file
指令删除(rm 就可以啦~不用加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 checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到我们删除了test.txt文件。现在有两种选择:
一、版本库中也删除这个文件:git rm file
删除掉,并且git commit -m ''
提交修改:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d17efd8] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
二、删错了,需要恢复回来:
$ git checkout -- test.txt
git chekcout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
4、远程仓库
git远程仓库为git的杀手级功能之一。Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。而且是没有主次之分的。而GitHub这个网站就是提供git仓库托管服务的。
注:hub就是枢纽的意思。
那么如何将本地电脑关联到自己的github账户上呢?
首先,找到自己电脑上的SSH key位置:
然后在github上找到添加key并进行添加:
title任意填写,key里面是
id_rsa.pub
文件内容。然后点击提交就可以了,这样就可以往自己的github上进行推送了。但是github上的项目是开源的,其他人都可以看见,但是不可以修改。当然也是可以花钱变成私有的。注:SSH 为 Secure Shell的缩写,即安全外壳协议。
4.1添加远程仓库
现在我们在本地有了一个git仓库,又想在github上有一个远程仓库。并让这两个仓库远程同步,这样远程仓库既可以当做备份,也可以多人进行协作工作。那么该怎么做呢?
首先,在github上找到一个"new repository"填写名字并新建仓库:
新仓库是这样的:
![(G5WGTMF~%J350FD$1U12]N.png](https://img.haomeiwen.com/i5704367/3ac60096be290c97.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这时,GitHub告诉我们可以关联一个本地仓库将内容推送上去,也可以新建一个仓库。这时按照提示在本地仓库执行下面的命令,关联远程仓库并推送:
git remote add origin git@github.com:beipinggao/2018-1-14.git
git push -u origin master
推送成功后就可以看到远程仓库和本地仓库有一样的文件:
![F]8D`5AY8M5GX4RLYS)BV9V.png](https://img.haomeiwen.com/i5704367/f827c6d9359c19da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
现在开始,本地提交了之后就可以通过
git push origin master
把本地提交推送到github上。
总结:
1、关联远程仓库:git remote add origin git@server-name:path/repo-name.git
2、第一次推送master分支内容时加 -u:git push -u origin maste
,u即upstream上游的意思。
3、之后本地向github远程分支提交:git push origin master
4.2从远程仓库克隆
只需输入下面指令就可以了:
git clone +git仓库地址
5、分支管理
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
5.1创建与合并分支
创建并切换到该分支:
$ git checkout -b dev
Switched to a new branch 'dev'
b即branch分支的意思,就相当于执行了下面的两行代码:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
可以用git branch
查看所有分支
$ git branch
* dev
master
- 其中,*代表当前所在的分支。
我们在Dev分支上进行修改之后,需要合并到master分支上该怎么做呢?
1、先切回主分支
$ git checkout master
Switched to branch 'master'
2、将dev分支内容合并到master分支上
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
3、删除dev分支
$ git branch -d dev
Deleted branch dev (was fec145a).
5.2解决冲突
假如在一个分支liu上进行修改提交,另一个分支master上也进行修改提交。
然后在主分支上进行分支和并git merge dev
的时候就会出现代码冲突的问题:
$ git merge liu
Auto-merging liu.txt
CONFLICT (content): Merge conflict in liu.txt
Automatic merge failed; fix conflicts and then commit the result.
这时,文件时这样的:
liuhuan
<<<<<<< HEAD
master
=======
dev
liu
>>>>>>> liu
可以看到冲突的代码是用箭头和等号来显示出来,我们修改冲突代码之后,需要重新git add
git commit
提交代码之后才可以重新merge:
$ git merge liu
Already up to date.
可以看到已经merge成功。
5.3bug分支
我们需要解决bug的时候,可以新建一个bug分支。然后进行修改,之后合并到主分支再进行删除就可以啦。
修改bug时,可以将开发分支gitstash
隐藏起来起来,之后再git stash pop
取消隐藏就可以了。
同样,添加新功能时也可以先建分支这样来处理。
5.4多人合作开发
有6点总结:
- 查看远程库信息,使用
git remote -v
; - 本地新建的分支如果不推送到远程,对其他人就是不可见的;
- 从本地推送分支,使用
git push origin branch-name
,如果推送失败,先用git pull
抓取远程的新提交; - 在本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致; - 建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
;
注:本地新建的分支如果没有关联远程分支推送到远程分支之后,在pull代码时就会报如下错误:
You asked me to pull without telling me which branch you
want to merge with, and 'branch.production.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.
If you often merge with the same branch, you may want to
use something like the following in your configuration file:
[branch "debug"]
remote = <nickname>
merge = <remote-ref>
[remote "<nickname>"]
url = <url>
fetch = <refspec>
See git-config(1) for details.
这个时候就需要关联一下远程分支
- 从远程抓取分支,使用
git pull
,如果有冲突,要先处理冲突。
6、标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
Git有commit,为什么还要引入tag?
“请把上周一的那个版本打包发布,commit号是6a5819e...”
“一串乱七八糟的数字不好找!”
如果换一个办法:
“请把上周一的那个版本打包发布,版本号是v1.2”
“好的,按照tag v1.2查找commit就行!”
所以,tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
1、标签管理常用命令:
- 命令
git tag <name>
用于新建一个标签,默认为HEAD即当前版本,也可以指定一个commit id; -
git tag -a <tagname> -m "blablabla..."
可以指定标签信息,标签信息可以采用PGP(一个加密协议)签名标签; - 命令
git tag
可以查看所有标签。是按字母排列的,不是按时间排列。
2、如何操作标签
-
命令
git push origin <tagname>
可以推送一个本地标签; -
命令
git push origin --tags
可以推送全部未推送过的本地标签; -
命令
git tag -d <tagname>
可以删除一个本地标签; -
命令
git push origin :refs/tags/<tagname>
可以删除一个远程标签。
6、关于GitHub的fork
fork:叉,分支的意思。就是将开源项目克隆到自己的GitHub远程仓库下。
三点总结:
1、在GitHub上,可以任意Fork开源仓库;
2、自己拥有Fork后的仓库的读写权限;
3、可以推送pull request给官方仓库来贡献代码。GitHub上有这个按钮,提供建议的。
具体的看这个解释很直接:https://www.zhihu.com/question/21682976
好了,就总结到这里吧,有什么问题了一会再来补充~