自报家门:因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
注意git config
命令的--global
参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
查看你的Git全局设置信息:
git config -l
本地库与远程库关联:
git remote add origin git@github.com...
创建版本库
通过git init
命令把目录变成Git可以管理的仓库:
$ git init
Initialized empty Git repository in /Users/learngit/.git/
瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录
添加文件到Git仓库,分两步:
第一步,使用命令git add <file>
,注意,可反复多次使用,添加多个文件;
第二步,使用命令git commit -m
,完成。
查看当前状态
- 要随时掌握工作区的状态,使用
git status
命令。 - 如果
git status
告诉你有文件被修改过,用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允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
。
穿梭前,用git log
可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog
查看命令历史,以便确定要回到未来的哪个版本(确定commit_id)。
工作区、暂存区、版本库
版本库(Repository)
工作区有一个隐藏目录.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区
,还有Git为我们自动创建的第一个分支master
,以及指向master的一个指针叫HEAD
。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
每次修改,如果不add到暂存区,那就不会加入到commit中。
撤销修改
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file
,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节git reset --hard commit_id
,不过前提是没有推送到远程库。
#删除文件
命令git rm
用于彻底删除一个文件(包括版本库中的修改)。
如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本(撤销工作区的修改即可git checkout -- file
),你会丢失最近一次提交后你修改的内容。
SSH
本地Git仓库和GitHub仓库之间的传输是通过SSH加密的。
ssh-keygen -t rsa -C "youremail@example.com"
- Client端用户将自己的公钥存放在Server上,追加在文件authorized_keys中。
- Server收到登录请求后,随机生成一个字符串str1,并发送给Client。
- Client用自己的私钥对字符串str1进行加密。
- 将加密后字符串发送给Server。
- Server用之前存储的公钥进行解密,比较解密后的str2和str1。
- 根据比较结果,返回客户端登陆结果。
创建分支
首先,我们创建dev分支,然后切换到dev分支:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
现在,当dev分支的工作完成了,我们可以切换回master分支:
$ git checkout master
Switched to branch 'master'
把dev分支的工作成果合并到master分支上:
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
合并完成后,就可以放心地删除dev分支了:
$ git branch -d dev
Deleted branch dev (was fec145a).
在这个过程中有三个指针:
- 指针master指向本地master分支最新提交的位置
- 指针dev指向本地dev分支最新提交的位置
- HEAD指针指向当前位置
注意:当Git无法自动合并分支时,即合并时发生了冲突,此时就必须首先解决冲突。解决冲突后,再提交,合并完成。
$ git merge dev
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
git status
也可以告诉我们冲突的文件:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: test.txt
点开冲突文件,冲突的内容一般就是下面这种形式:
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
解决完冲突之后,进行git add
和 git commit
即可。
保存当前工作现场
在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,当前正在dev上进行的工作还没有提交,该怎么办呢?
Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
$ git stash
Saved working directory and index state WIP on dev: 6224937 add merge
HEAD is now at 6224937 add merge
当bug修复完,再git stash pop
,恢复工作现场。
多人协作时push和pull
- 从本地推送分支,使用
git push origin branch-name
,如果推送失败,先用git pull
抓取远程的新提交; - 在本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致; - 建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
; - 从远程抓取分支,使用
git pull
,如果有冲突,要先处理冲突。
注意:git push origin branch-name
,当远端没有关联的分支branch-name时,就在远端创建对应的分支。
配置
让Git显示颜色,会让命令输出看起来更醒目:
$ git config --global color.ui true
别名,用st表示status:
$ git config --global alias.st status