版本库可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
创建版本库
git init 后 文件夹会产生.git 文件其作用为跟踪管理版本库的。
添加文件
言归正传,现在我们编写一个readme.txt文件,内容如
Git is a version control system.
Git is free software.
第一步,用命令git add <file name>告诉Git,把文件添加到暂存区:执行上面的命令,没有任何显示,这就对了
git add . 可提交当前仓库中所有文件。
git add a.txt b.txt 可指定多个文件添加至暂存区
第二步,用命令git commit -m <备注>告诉Git,把文件提交到仓库:
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
-m : 本次提交修改的备注
版本穿梭
a文档已提交三次版本
版本一:
我是Ws
版本二:
我是Ws
我爸是Wjm
版本三:
我是Ws
我爸是Wjm
我妈是Wcl
版本回退
前言:打游戏时每通过一关都会手动保存,以便可以在闯关失败时返回上一关卡。 git 也是同理为了防止文件下次改动出错,通过每次commit产生的快照id返回之前的版本。
当文件提交的版本过多且我们需要返回某一版本时,怎么才能查找到其历史版本的快照id囊?
查找历史版本快照
git log可以查看文件的提交的历史记录。
$ git log
commit 1b19a4b1db592f744ee073f64f24b249cd75e04f (HEAD -> master)
Author: ws <1535191556@qq.com>
Date: Thu Jan 18 10:06:18 2024 +0800
mather
commit f1ed86a7d60ee360f933878a495b4de2d52b051e
Author: ws <1535191556@qq.com>
Date: Thu Jan 18 09:46:18 2024 +0800
father
commit 3e690b17a485537c27a326630529748767ea8243
Author: ws <1535191556@qq.com>
Date: Thu Jan 18 09:45:43 2024 +0800
add a.txt
可以看到相关信息,最重要的commit参数为版本快照Id。
如果a文档像回退到上一版本,使用 git reset --hard HEAD^:返回至上一个版本。
Git必须知道当前版本是哪个版本,HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,以此类推上100个需要100个^十分难搞,所以写成HEAD~100。
ws@DESKTOP-75BQIUH MINGW64 ~/Desktop/t (master)
$ git reset --hard HEAD^
HEAD is now at f1ed86a father
现在就还原到了第二个版本
我是Ws
我爸是Wjm
此时查看版本历史日志发现回退前的版本快照已经消失了?如果没有快照id我们就不能重返未来了?
解决方法:
1 如果git窗口还在可以向上查找那次commit得到快照id。
2.如果git窗口已关闭则通过git reflog 记录你的每一次命令获取快照。
$ git reflog
f1ed86a (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
1b19a4b HEAD@{1}: commit: mather
f1ed86a (HEAD -> master) HEAD@{2}: reset: moving to HEAD^
236bddb HEAD@{3}: commit: mather
f1ed86a (HEAD -> master) HEAD@{4}: commit: father
3e690b1 HEAD@{5}: commit (initial): add a.txt
回到未来
通过git reflog找到其未来版本的快照id再通过git reset --hard 快照id
$ git reset --hard 236bddb
HEAD is now at 236bddb mather
查看a,果然恢复到了未来的版本。
我是Ws
我爸是Wjm
我妈是Wcl
总结
git reset --hard HEAD^ 返回上一版本
git reset --hard 版本快照id 返回任意指定版本
工作区和版本区
工作区为当前仓库的根目录,隐藏目录.git,这个不算工作区,而是Git的版本库。
还有Git为我们自动创建的第一个默认分支master,以及指向master的一个指针叫HEAD
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
案例www.liaoxuefeng.com/wiki/896043…
管理修改
因为Git跟踪并管理的是修改,而非文件。
你会问,什么是修改?比如你新增了一行,删除了一行,更改了某些字符,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。
为什么、说Git管理的是修改,而不是文件呢?
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.
然后,添加:
$ git add readme.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#
然后,再修改readme.txt:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
提交:
$ git commit -m "git tracks changes"
[master 519219b] git tracks changes
1 file changed, 1 insertion(+)
提交后,再看看状态:
$ 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")
仓库状态显示 modified: readme.txt ? 为什么我已经提交了修改但确还显示存没提交修改的文件囊?
看一下过程:第一次修改 -> git add -> 第二次修改 -> git commit
第二次修改没有git add 提交至暂存区所以git commit只提交了第一次修改。
至此可以发现git 管理的是修改而不是文件。
查看工作区和版本库里此文件最新版本的区别
提交后,用git diff HEAD -- readme.txt命令可以查看工作区和版本库里此文件最新版本的区别:
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.
撤销修改
撤销工作区的修改
$ git restore 文件名,撤回工作区的修改;
撤回后$ git status 查看下工作区状态:nothing to commit, working tree cleanb成功
$ git status
On branch master
nothing to commit, working tree clean
撤回暂存区的修改
如果将工作区的修改通过git add . 加入暂存区怎么撤销囊?
git restore --staged <file> :即可撤回暂存区提交的修改,但是工作区的修改依旧存在。可通过git restore 文件名再次撤回工作区修改,至此完成撤回.
撤回版本库的修改
当版本库文件没有推送至远程仓库情况下,可以通过回git reset --hard 版本id退版本达到撤回。
删除文件
当提交a文件至版本库后删除工作区的a文件.
查看状态: Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了,要从版本库中删除该文件,那就用命令git rm删掉,并且git commit提交版本更新。
$ 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: a.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git rm a.txt
rm 'a.txt'
$ git commit -m 'rm a.txt'
[master 6d63bde] rm a.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 a.txt
撤销删除
如果在工作区误删a文件,可通过$ git restore 文件名撤销本次修改,在之后使用版本库最新的文件代替,但会丢失删除文件前的修改内容,因为此内容没有commit快照。
github
提供Git仓库托管服务的网站,可提供一个免费的远程仓库。
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
如果用户目录下.ssh目录中有id_rsa和id_rsa.pub这两个文件则可以跳过。
如果没有则通过如下代码创建SSH Key
创建SSH Key
$ ssh-keygen -t rsa -C "youremail@example.com"
以上操作后一路回车完成后.ssh目录下出现id_rsa和id_rsa.pub
id_rsa.pub为公钥;id_rs为私钥。
在gitHub的settings中 找到 ssh and gpg keys 添加公钥, 这下gitHub当前账户下的所有库只认准拥有被添加的公钥用户提交修改。
在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)
添加远程库
前提条件,你已经在本地创建了一个Git仓库后。又想在GitHub创建一个远程仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。
gitHub创建库
本地库和远程进行关联
$ git remote add origin(默认的远程库名) git@github.com:michaelliao/learngit.git(远程库地址)
删除远程库关联
当本地库关联错远程库,可通过$ git remote rm origin(关联库名)解绑。
仅仅只是解除本地库和绑定库的关系。
当忘记本地库关联的远程库名时可通过$ git remote -v查看。
本地库提交修改至远程库
$ git push -u origin master 其将本地 master分支的改动提交给远程库对应分支,并将本地库当前分支和远程库对应分支相关联,在以后的推送或者拉取时就可以简化命令。
本地库拉取远程库的最新修改
当其他成员上传了最新的修改后如何将本地库进行更新囊?
通过 git pull 库名 被拉取的分支 进行更新。
本地克隆远程库
上次我们讲了先有本地库,后有远程库的时候,再而如何关联远程库。
现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,克隆远程库。
$ git clone git@github.com:michaelliao/gitskills.git