首先设置用户名和邮箱
$ git config --global user.name "qianmofuyun"
$ git config --global user.email "2811042113@qq.com"
$ mkdir learngit 创建一个文件夹
$ cd learngit 进入这个文件夹
$ pwd 显示当前文件夹路径
$ git init 把这个目录变成Git可以管理的仓库
$ ls -ah 如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见
把文件添加到版本库:
第一步,用命令git add告诉Git,把文件添加到仓库:
$ git add readme.txt 文件一定要在当前仓库目录下
第二步,用命令git commit告诉Git,把文件提交到仓库
$git commit -m "message"
简单解释一下git commit命令,-m后面输入的是本次提交的说明,
可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
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")
上面的命令输出告诉我们,readme.txt被修改过了,但还没有准备提交的修改
git diff命令查看和之前版本的不同
$ git diff 查看和之前版本的不同
diff --git a/readme.txt b/readme.txt
index d8036c1..d55a7b6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,4 @@
Git is a version control system.
+Git is free software.
+Git is a distributed version control system.
Git is free software.
\ No newline at end of file
git diff顾名思义就是查看difference,查看和之前版本的不同
提交修改和提交新文件是一样的两步
第一步是git add
qianm@DESKTOP-C75C6QK MINGW64 ~/learngit (master)
$ git add readme.txt
第二步git commit
qianm@DESKTOP-C75C6QK MINGW64 ~/learngit (master)
$ git commit -m "add ---"
[master bfad96f] add ---
1 file changed, 2 insertions(+)
小结
要随时掌握工作区的状态,使用git status命令。 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
git log命令显示从最近到最远的提交日志
$ git log
commit e4d0fff3ce4eff2bb0ba0bd49e7d49b81d68c2ed (HEAD -> master)
Author: qianmofuyun <2811042113@qq.com>
Date: Sun Jun 17 00:35:48 2018 +0800
three
commit bfad96f6230d1a22328bdc23e273b26ea0581808
Author: qianmofuyun <2811042113@qq.com>
Date: Sun Jun 17 00:30:05 2018 +0800
add ---
commit 3cd3ba543e28d6ba253ce4e5b1efb87726e1b8d2
Author: qianmofuyun <2811042113@qq.com>
Date: Thu Jun 14 17:21:53 2018 +0800
123456
可以看到我们提交了三次,每次提交的时间和提交的版本名称
版本回退
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^, 上上一个版本就是HEAD^^ ,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
使用git reset命令:
$ git reset --hard HEAD^
HEAD is now at bfad96f add ---
回退到了上一个版本
再查看全部版本
$ git log
commit bfad96f6230d1a22328bdc23e273b26ea0581808 (HEAD -> master)
Author: qianmofuyun <2811042113@qq.com>
Date: Sun Jun 17 00:30:05 2018 +0800
add ---
commit 3cd3ba543e28d6ba253ce4e5b1efb87726e1b8d2
Author: qianmofuyun <2811042113@qq.com>
Date: Thu Jun 14 17:21:53 2018 +0800
123456
最新的那个版本已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办? 办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个版本的commit id是(e4d0...),于是就可以指定回到未来的某个版本:
$ git reset --hard e4d0 只要前几位就行
HEAD is now at e4d0fff three
Git提供了一个命令git reflog用来记录你的每一次命令:
$ git reflog
e4d0fff (HEAD -> master) HEAD@{0}: reset: moving to e4d0
bfad96f HEAD@{1}: reset: moving to HEAD^
e4d0fff (HEAD -> master) HEAD@{2}: commit: three
bfad96f HEAD@{3}: commit: add ---
3cd3ba5 HEAD@{4}: commit (initial): 123456
小结
- HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
- 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
- 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
工作区和暂存区
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区:
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
撤销修改
如果你在工作区的修改想放弃(还没有添加)
git checkout -- file 命令:可以丢弃工作区的修改
$ git checkout -- readme.txt
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区之后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
如果你的修改想放弃(已经添加到暂存区,但还没有提交)
git reset HEAD <file>命令可以把暂存区的修改撤销掉,重新放回工作区
$ git reset HEAD readme.txt
Unstaged changes after reset:
M LICENSE.txt
小结
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,
$ git reset --hard HEAD^
删除文件
$ rm test.txt 在工作区删除test.txt文件
现在你有两个选择
一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "sanchu"
[master b4f421a] sanchu
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 test.txt
现在,文件就从版本库中被删除了
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
$ git checkout -- test.txt
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
小结
命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
远程仓库
第1步:创建SSH Key
在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C "qianmofuyun@163.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/qianm/.ssh/id_rsa):
Created directory '/c/Users/qianm/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/qianm/.ssh/id_rsa.
Your public key has been saved in /c/Users/qianm/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+wpYauVmZoC3WYk0WEHfL8yQ4jYVS2O4a9jk0BoJR1Q qianmofuyun@163.com
The key's randomart image is:
+---[RSA 2048]----+
| oooEo= |
|. .o.+ * |
| o.o+.* . |
| +++= = . |
| .OB.= S . |
| oo=% o |
| .* B . |
| . = . . |
| ... |
+----[SHA256]-----+
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,
由于这个Key也不是用于军事目的,所以也无需设置密码。
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
第2步:登陆GitHub,打开“settings”(设置),“SSH and GPG keys”页面:
填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容 为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
添加远程库
首先,登陆GitHub,然后,在右上角找到“new repository”按钮,创建一个新的仓库:
在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库: 目前,在GitHub上的这个learngit仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库
现在,我们根据GitHub的提示,在本地的learngit仓库下运行命令:
$ git remote add origin https://github.com/qianmofuyun/learngit.git
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
下一步,就可以把本地库的所有内容推送到远程库上:
$ git push -u origin master
fatal: HttpRequestException encountered.
▒▒▒▒▒▒▒▒ʱ▒▒▒▒
Username for 'https://github.com': qianmofuyun
Counting objects: 16, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (16/16), 1.27 KiB | 435.00 KiB/s, done.
Total 16 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), done.
To https://github.com/qianmofuyun/learngit.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
根据提示输入用户名密码
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样:
从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master分支的最新修改推送至GitHub
SSH警告
当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:
这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。
Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:
小结
要关联一个远程库,使用命令
$ git remote add origin https://github.com/qianmofuyun/learngit.git
关联后,使用命令
$ git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令
$git push origin master推送最新修改;
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
从远程库克隆
上次我们讲了先有本地库,后有远程库的时候,如何关联远程库。
现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。
首先,登陆GitHub,创建一个新的仓库,名字叫learngit2:
勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。创建完毕后,可以看到README.md文件:
现在,远程库已经准备好了,下一步是用命令git clone克隆一个本地库:
$ git clone https://github.com/qianmofuyun/learngit2.git
Cloning into 'learngit2'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
把Git库的地址换成你自己的,然后进入learngit2目录看看,已经有README.md文件了:
$ cd learngit2
$ ls
README.md
如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。
你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。
使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。
小结
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。