目录
Git简介
Git能够保存代码的各个版本,每个版本文件的修改、删除,Git 都会跟踪,以便任何时候都可以追踪历史或者在将来某一时刻可以还原。
Git安装
- 首先来到git的官方网址链接: git下载链接。点击macOS;
- 选择安装方式,因为我没有homebrew,所以我就选择文件直接安装;
- 点击download即可;
- 一步步点击,安装成功;
- 在终端中输入git --version出现版本号即可。
工作区/暂存区/本地仓库/远程仓库
- Workspace:工作区;
- Index / Stage:暂存区;
- Repository:本地仓库;
- Remote:远程仓库;
增加暂存区的好处
- 分批、分阶段递交,降低了commit的颗粒度;
- 进行快照,便于回退;
创建版本库
在当前目录新建一个Git版本库
git init
新建一个目录,将其初始化为Git版本库
git init [project-name]
克隆一个项目和它的整个代码历史
git clone [url]
添加文件到暂存区
添加工作区指定文件到暂存区
git add [file1] [file2] ...
添加工作区指定目录到暂存区,包括子目录
git add [dir]
添加工作区所有内容到暂存区
git add .
提交到本地仓库
提交暂存区所有内容到本地仓库
git commit -m [message]
提交暂存区的指定文件到本地仓库
git commit [file1] [file2] ... -m [message]
修改commit注释
本地修改最后一次注释
git commit --amend
压缩合并多次提交
git rebase -i [startpoint] [endpoint]
其中-i的意思是–interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint] [endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支HEAD所指向的commit(注:该区间指定的是一个前开后闭的区间)。
// 合并最近的两次提交
git rebase -i HEAD~3
执行这个命令后会跳到一个vi编辑器
里面的提示有:
pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)
- 越往下提交越新,且只能从新提交往旧提交合并,合并后代码为最新的那个提交;
- 如果endpoint不是最新的提交,则合并后只保留合并后的提交以及更旧的提交,最新的提交到合并的提交之间的提交全部丢失。
关联远程库
关联远程仓库前的设置
- 由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一些设置;
- 创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:ssh-keygen -t rsa -C “youremail@example.com”;
- 需要把邮件地址换成自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人;
- 登陆GitHub,打开“Account settings”,“SSH Keys”页面。然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容;
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
关联一个远程库(关联远程库时必须给远程库指定一个别名,origin是默认习惯命名)
git remote add origin git@server-name:path/repo-name.git
origin为远程库别名,git@server-name:path/repo-name.git为远程库地址
推送本地仓库分支的变化到远程库分支
git push [远程库别名] [本地分支名]:[远程分支名]
如果本地分支名与远程分支名相同,则可以省略冒号
git push [远程库别名] [本地分支名]
以下命令将本地的 master 分支推送到 origin 主机的 master 分支
git push origin master
或者
git push origin master:master
如果远程库没有那个远程分支,将自动创建。
取回远程库分支的变化,并与本地分支合并
git pull [远程库别名] [远程分支名]:[本地分支名]
例:将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并。
git pull origin master:brantest
如果远程分支是与当前分支合并,则冒号后面的部分可以省略
git pull origin master
显示远程库
# 显示远程库
$ git remote
origin
# 显示远程库更详细的信息
$ git remote -v
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)
上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
从远程库克隆
- 先创建远程库:登陆GitHub,创建一个新的仓库,名字叫gitskills;
- 勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件;
- 用命令git clone克隆一个本地库:
git clone git@github.com:sunshichong/gitskills.git
;
分支
查看分支
查看所有本地分支
git branch
查看所有分支(包括远程)
git branch -a
查看所有本地分支及其当前所在提交记录的哈希值
git branch -v
查看所有本地分支及其当前所在提交记录的哈希值,以及和其上游分支的相对位置
git branch -vv
创建分支
git branch <分支名>
切换分支
git checkout <分支名>/git switch <分支名>
创建+切换分支
git checkout -b <分支名>/git switch -c <分支名>
合并某分支到当前分支
git merge <分支名>
删除分支
- 删除本地分支
git branch -D <分支名>
- 删除远程分支
git push origin --delete <分支名>
将远程主机的更新全部取回本地
git fetch origin
本地分支与远程分支建立关联
1 本地分支已存在
git branch --set-upstream-to=origin/remote_branch local_branch
关联以后可以直接git pull/push,未关联必须git pull/push origin…
2 本地分支不存在
git checkout -t origin/remote_branch
自动新建一个与远程分支同名的本地分支,且内容一致
修改分支名称
1 本地分支重命名(还没有推送到远程)
git branch -m oldName newName
2 远程分支重命名 (已经推送远程-假设本地分支和远程对应分支名称相同)
2.1 重命名远程分支对应的本地分支
git branch -m oldName newName
如果修改当前分支:
git branch -m newName
2.2 删除远程分支
git push --delete origin oldName
2.3 上传新命名的本地分支
git push origin newName
2.4 把修改后的本地分支与远程分支关联
git branch --set-upstream-to=origin/remote_branch local_branch
2.5 如果在当前分支,可以合并2.3和2.4
git push --set-upstream origin newName
撤销
暂存区覆盖工作区
git checkout -- <文件名>
git checkout .
版本库覆盖暂存区
git reset HEAD <文件名>
git reset HEAD
版本库覆盖暂存区和工作区
git reset --hard HEAD
版本库回退到上一个提交版本,同时覆盖暂存区和工作区
git reset --hard HEAD^
版本库回退到上n个提交版本,同时覆盖暂存区和工作区
git reset --hard HEAD~n
版本库回退到某一个历史提交版本(结合git log/reflog命令),同时覆盖暂存区和工作区
git reset --hard commit_id
配置
Git的配置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
显示当前的Git配置
git config --list
编辑Git配置文件
git config -e [--global]
设置提交代码时的用户信息
git config [--global] user.name "[name]"
git config [--global] user.email "[email address]"
查看差异
查看在上次提交之后是否有修改
git status
查看工作区和暂存区的差异内容
git diff
查看暂存区和版本库的差异内容
git diff --cached
查看工作区和版本库的差异内容
git diff HEAD
查看两分支的差异(也可用于两次不同提交)
显示两分支有差异的文件列表
git diff branch1 branch2 --stat
显示两分支所有文件的详细内容差异
git diff branch1 branch2
显示两分支指定文件的详细差异
git diff branch1 branch2 具体文件路径
比较的分支包括远程分支
git diff <local branch> <remote>/<remote branch>
例:git diff master origin/master
查看历史提交记录
查看某一分支提交记录
git log / git log 分支名
查看某一分支从哪个分支创建的
git reflog 分支名
查看所有分支的顺序提交记录(即HEAD的提交记录)
git reflog
合并冲突问题
冲突的3种情况
- 多个分支同时编辑不同文件:自动合并(保留所有的修改);
- 多个分支同时编辑相同文件的不同地方:自动处理冲突(保留所有的修改);
- 多个分支同时编辑相同文件的同一个地方:必须手动解决冲突;
手动解决冲突示例
- 当两个分支各自有了新的提交,在合并时很容易产生合并冲突;
-
当处于master分支进行git merge feature1产生冲突时,先根据Git的指示手动解决冲突(和其他人沟通),然后add、commit;
-
这时如果切回feature1分支进行git merge master,将直接Fast-forward合并成功,因为master当前的提交记录正领先feature1一个提交。
查看分支提交图
git log --graph
查看分支提交简略图
git log --graph --pretty=oneline --abbrev-commit
远程push时合并冲突
- 首先,试图用
git push [远程库别名] [本地分支名]:[远程分支名]
推送自己的修改; - 如果推送失败,则意味着远程分支比本地分支更新,需要先用git pull试图合并;
- 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用
git push [远程库别名] [本地分支名]:[远程分支名]
推送就能成功。
删除
删除暂存区文件
git rm --cached <file>
删除本地仓库中的文件
git rm <file>
Git集成IDEA后的文件颜色含义
红色:未加入版本控制;
灰色:版本控制忽略文件;
绿色:已加入,但没有提交过;
白色:已加入,提交过,无改动;
蓝色:已加入,提交过,有改动;