很多人都有这样的感慨!要是人生能重来,会有不一样的人生…… 也许时间可以穿梭,那也只能是记忆,至少现阶段是这样,或许有一天真的会有时光穿梭机…… 相对于人生的这种遗憾,Git给code的一生带来了太多的惊叹,记录着code每一次提交的变化,让code可以有不一样的码生,更是可以让code穿梭到生命的任意时刻。Perfect……
1. 工作流程
- workspace 工作区
- index/stage 缓存区/暂存区
- repository 仓库区/本地仓库
- remote 远程仓库
2. 安装配置(Mac)
#mac 下使用 homebrew 安装 @2.25.0指定版本,如果不指定则安装最新版本
brew install git@2.25.0
#使用git提交文件/代码时,会附带上当前操作者信息,author和commiter
#默认的格式为:user.name<user.email>es:Author: zhaosl <zhaoshoulai@aliyun.com>
#在git中查看历史时,会通过操作者信息来确定谁修改了哪些文件/代码
#user.email和user.email在git config中定义
#git config有全局配置和当前仓库配置之分。
#若当前仓库中的git config未定义user.name和user.email,则取全局git config中的user.email和user.email。若定义了,则取当前仓库git config中的user.email和user.email
#配置全局 user.name
git config --global user.name "zhaosl"
#配置全局邮箱
git config --global user.email "zhaoshoulai@aliyun.com"
#查看全局配置
git config --local --list
3. 一个人玩
3.1 配置远程仓库
1. 创建远程仓库(gitee)
点击右上角 + 新建仓库
填写仓库名称、归属、路径、仓库介绍、是否开源、选择语言、添加.gitIgnore文件、选择初始化这个库的方式、选择git-flow(怎么选择比较合适的flow后面会涉及到)
-
点击“创建按钮” 就创建好了 es:https://gitee.com/qzhd/git-note.git
注:远程仓库是必须创建的
2. 添加ssh公钥
如果不加入ssh公钥,每次访问远程仓库都需要输入用户名密码,为了省去该麻烦,我们需要在gitee上添加自己的公钥;首先生成公钥:
#这里填写自己的邮箱,其实这里和git配置的邮箱一致不一致没有什么关系
ssh-keygen -t rsa -C "zhaoshoulai@aliyun.com"
#查看SSH公钥,复制备用,你会看到一大串
cat ~/.ssh/id_rsa.pub
- 添加公钥
在右上角自己头像附近的三角号下拉点击设置
在左导航--安全设置--SSH公钥
-
写一个标题(比如是用自己的电脑可以写my-mac) 公钥就粘贴自己复制的公钥
注:不同电脑都需要免密要访问,那么就需要每个电脑都需要添加自己的SSH公钥
3.2 新建本地仓库
-
本地新建仓库
#第一步 创建一个本地版本库 git-note 并进入(其实就是一个目录) mkdir git-note & cd git-note #初始化 这时候才是真正意义上由一个目录转变为本地仓库 #注意,执行完初始化命令,会在给目录下多一个.git目录,该目录就是本地仓库的核心,表乱动 git init #或者直接 git init git-note 更省事
-
clone远程仓库
#默认克隆下来远程仓库,但只有master分支,本地也创建了master分支并与远程master分支建立映射追踪 git clone git@gitee.com:qzhd/git-note.git
3.3 建立本地仓库与远程仓库的联系
-
针对本地已有版本库
#初始化(会做很多工作:创建缓存区、本地仓库;直观上你会看到一个.git目录) git init #建立远程地址的别名:origin代表git@gitee.com:qzhd/git-note.git(这个是我一个远程仓库地址) #如果你这个项目托管到多个代码平台es:githup、gitee等,你可以分别创建不同的别名 #如果你是clone下来的项目 不需要执行下面这条命令 #如果你是自己初始化项目(git init) 且没有创建过该别名与远程仓库的映射 则需要执行 git remote add origin git@gitee.com:qzhd/git-note.git #分支 'master' 设置为跟踪来自 'origin' 的远程分支 'master' git branch --set-upstream-to=origin/master master #把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。执行此命令后会要求输入用户名、密码,验证通过后即开始上传,如果加入了sshkey,不会要求输入用户名密。 git push -u origin master #git push 有可能报错,会让你先git pull,前分支的最新提交落后于其对应的远程分支也会报错 #fatal: 拒绝合并无关的历史 Note about fast-forwards 可以执行下面指令,然后在git push git pull origin master --allow-unrelated-histories
-
新建分支与远程分支建立联系
#创建一个分支并切换到该分支(如果已经存在该分支则不要加 -b ) #注意这个会在当前分支上创建develop分支,一般会指定master哦 #git checkout -b develop master git checkout -b develop #分支 'develop' 设置为跟踪来自 'origin' 的远程分支 'develop' git branch --set-upstream-to=origin/develop develop #git pull & git push 就不用带着origin develop 了 ^_^! #or 如果远程仓库有某个分支,比如develop分支 #develop本地仓库分支(可以自定义名字,但最好和远程仓库名称保持一致) origin/develop 远程分支 git checkout -b develop origin/develop #or 使用-t参数,默认会在本地建立一个和远程分支名字一样的分支 git checkout -t origin/develop
3.4 修改操作
-
添加文件 --> 缓存区 --> 本地仓库 --> 远程仓库
#第一步 创建一个文件 workspace发生了变化 touch test & echo "create test file" > test #查看变动信息(红色表示未添加到index,绿色表示已经添加到index但没有提交到本地仓库) git status #第二步 加入到暂存区(维护修改记录)workspace的变化维护到index git add test # 或者 git add . “.” 表示所有文件 #第三步 修改记录提交到本地仓库 这里我们使用git commit -m'描述信息'简单的提交, #后续展开更多commit用户及使用规范 git commit -m'add(test):add a file named test' # push到远程仓库别名为origin的develop分支 git push origin develop
-
修改文件到本地仓库
#修改test 添加一句话 echo "first update test file" >> test #可以看一下test文件的变化, 可以看到 +first update test file #a/test:修改之前 b/test:修改之后 git diff test diff --git a/test b/test index f0324dd..94a7431 100644 --- a/test +++ b/test @@ -1 +1,2 @@ create test file +first update test file #可以看出来workspace的修改提交到本地仓库,一般套路就是add -> commit git add . git commit -m'feat(test):add a word to test' # push到远程仓库别名为origin的develop分支 git push origin develop
3.5 查看信息总结
#显示变更的文件
git status
#显示当前分支的版本历史
git log
#根据关键词搜索提交历史
git log -S <关键词>
#显示所有提交过的用户,按照提交次数排序
git shortlog -sn
#显示指定文件是什么人,什么时间改过
git blame <file>
#显示暂存区和工作区的差异
git diff
#显示暂存区和上一个commit的差异
git diff --cached <file>
#显示工作区域最新commit的差异
git diff HEAD
#显示两次commit的不同
git diff HEAD HEAD~2
#显示你今天写了多少行代码
git diff master --shortstat "@{0 day ago}"
#显示当前分支的最近几次提交
git reflog
3.6 回退、恢复
1. 回退、恢复某版本(commit)
-
查看提交历史记录
#可以看到 两次提交记录,这里也可以看到 描述信息、Author:user.name user.email git log commit a34a2a12d4da7f5bf935369764a4baa572cbfe10 (HEAD -> master) Author: zhaosl <zhaoshoulai@aliyun.com> Date: Sun Apr 5 12:48:33 2020 +0800 feat(test): add one word to test commit e7348eecdf40a278f61a13837aff4c1b90dc0ce6 Author: zhaosl <zhaoshoulai@aliyun.com> Date: Sun Apr 5 11:50:44 2020 +0800 add(test):add a file named test #如果嫌弃现实的内容过多,可以看一下git log更详细的用法,我这里只是入门,不讨论那么细 git log --pretty=oneline a34a2a12d4da7f5bf935369764a4baa572cbfe10 (HEAD -> master) feat(test): add one word to test e7348eecdf40a278f61a13837aff4c1b90dc0ce6 add(test):add a file named test
-
回退到某个版本
#回退到上一个版本 HEAD~n n=1,2,3…… git reset --hard HEAD^ # git reset --hard HEAD~1 #可以看到现在回退到上一个版本了 git log --pretty=oneline e7348eecdf40a278f61a13837aff4c1b90dc0ce6 (HEAD -> master) add(test):add a file named test or #git reset --hard 版本号 和 git reset --hard HEAD^ 效果是一样的 #版本号可以不写这么长,前几位就可以 es: e7348eec git reset --hard e7348eecdf40a278f61a13837aff4c1b90dc0ce6
-
恢复到某个版本
#现在使用git log只能看到一个版本 git log --pretty=oneline e7348eecdf40a278f61a13837aff4c1b90dc0ce6 (HEAD -> master) add(test):add a file named test #我想恢复到退回之前的版本,怎么办?首先得知道回退之前的版本是什么? #git reflog能查到每次回退和恢复;a34a2a1 就是回退之前的版本了 git reflog e7348ee (HEAD -> master) HEAD@{0}: reset: moving to HEAD~1 a34a2a1 HEAD@{1}: commit: feat(test): add one word to test e7348ee (HEAD -> master) HEAD@{2}: commit (initial): add(test):add a file named test #恢复到 a34a2a1 git reset --hard a34a2a1 #再用git log 看一下,恢复了 git log --pretty=oneline a34a2a12d4da7f5bf935369764a4baa572cbfe10 (HEAD -> master) feat(test): add one word to test e7348eecdf40a278f61a13837aff4c1b90dc0ce6 add(test):add a file named test
2. 撤销修改和删除文件
-
撤销修改
#如果上一次commit之后修改都需要撤销 git reset --hard HEAD^ #如果修改了很多文件,只有一个文件需要撤销 -- 前后都有空格 否则就是切换分支了 #git checkout -- 撤销修改有两种情况:(注意) #1. file修改后,还没有放到暂存区,使用撤销修改就回到和版本库一模一样的状态。 #2. file已经放入暂存区了,接着又作了修改,撤销修改就回到添加暂存区后的状态 git checkout -- file
-
删除版本库文件
#如果知道要删掉那些内容() rm -rf 文件 git add . git commit -m'' #同时从工作区和索引中删除文件。即本地的文件也被删除了 = rm -rf 文件 & git add . git rm 文件 #从索引中删除文件。但是本地文件还存在, 只是不希望这个文件被版本控制 git rm --cached 文件 #但无论是那种最后都需要 git commit
3.7 本地分支管理
#查看分支
git branch
#创建分支
git branch <name>
#创建分支指向指定commit
git branch <name> <commitId>
#切换分支
git checkout <name>
#从当前分支创建branch,并切换到该分支
git checkout -b <name>
#从某个分支创建branch 并切换到该分支
git checkout -b <new-branch-name> <branch-name>
#从某个tag创建一个分支
git checkout -b <branch-name> <tag-name>
#合并某分支到当前分支
git merge <name>
#选择一个commitId合并进当前分支
git cherry-pick <comitId>
#切换分支
git checkout <name>
#删除本地分支
git branch -d develop
#### 远程分支操作 ####
# 列出所有远程分支
git branch -r
#从当前本地分支新建远程分支
git push -u origin <branch-name>
#删除远程分支
git push origin --delete <branch-name>
#或者
git branch -dr <branch-name>
3.4 tag管理
tag和branch的区别是,tag是快照,不可以回退、修改等操作,就是当时那个时刻的一个状态;branch是可以回退、修改等操作。tag的作用一般是发布一个版本如Snapshot、Release 、v2.3.0等等。所以tag是建立在某次commit的上的。
#列出所有tag
git tag
#在当前commit上新建tag
git tag <name>
#在指定commitId上创建tag
git tag <name> <commitId>
#删除本地tag
git tag -d <name>
#删除远程tag
git push origin :refs/tags/<name>
#查看tag信息
git show tag
#提交指定tag
git push origin <name>
#提交所有的tag
git push origin --tags
#从某个tag创建一个分支
git checkout -b <branch-name> <tag-name>