设置
$ git config --global user.name "Your name"
$ git config --global user.email "exp@example.com"
创建
$ mkdir learngit # 创建文件夹
$ cd learngit
$ pwd # 当前目录显示
$ git init # 将目录初始化为git仓库
$ ls -ah # 显示隐藏文件,例如 .git
添加、提交
$ git add readme.txt # 提交指定文件
$ git add . # 提交全部文件
$ git commit - m "write a readme file"
注意 :Git命令必须在Git仓库目录内执行(git init除外)
查看
$ git status # 查看仓库状态
$ git diff readme.txt # 查看工作区和暂存区版本差异
$ git dff --cached # 查看暂存区和版本库差异
$ git dff HEAD --readme.txt # 查看工作区和版本库差异
$ cat readme.txt # 查看文件内容
$ git log # 查看提交记录
$ git log --pretty=oneline # 将提交记录整理成行显示(便于查看)
$ git reflog # 命令日志(比如用于找到某个commit id)
版本回退
$ git reset --hard HEAD^ # 回退到上个版本
$ git reset --hard HEAD^^ # 回退到上上个版本(^^^……,上上上...个)
$ git reset --hard HEAD~100 # 回退到第上100个版本
$ git reset --hard 1094a # 回退指定版本,(这里1094a是commit id的示例)
撤销修改
# 修改还没有add到暂存区
$ git checkout -- readme.txt # 使文件内容回到上一次commit或add时的状态(丢弃工作区修改)
# 如果已经add到暂存区
$ git reset HEAD readme.txt # 将暂存区修改回退到工作区(之后再丢弃工作区修改)
注意:git checkout – file命令中的–很重要,没有–,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。
删除、恢复
# 删除了文件
rm test.txt
# 继续从版本库删除
$ git rm test.txt
$ git commit -m "remove test.txt"
# 从版本库恢复
$ git checkout -- test.txt
创建SSH Key
# user目录下→ .ssh目录 → 检查是否有 id_rsa、id_rsa.pub文件,若无则需创建
# .ssh目录下
$ ssh-keygen -t rsa -C “youremail@example.com” # 使用默认值,无需加密,一路回车
# id_rsa 是私钥,不要泄露; id_rsa.pub是公钥,可公开
登录Github, 打开"Account settings","SSH Keys"页面 → “Add SSH Key” → 粘贴 id_rsa.pub内容
远程关联、同步
远程空仓库创建成功后,与本地仓库进行关联
$ git remote add origin git@github.com:username/repositoryname.git
# username:你的github账号名; repositoryname:你的github仓库名
# 本地仓库推送到远端仓库
$ git push -u origin master
$ git push origin master # 推送指定分支
注意:
- 由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令;
- 关联一个远程库时必须给远程库指定一个名字,origin是默认习惯命名;
- 假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。
查看、删除远程库
# 先查看远程库信息
$ git remote -v
$ git remote rm origin
注意:此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除
创建、合并分支
# 创建dev分支,然后切到dev分支上
$ git checkout -b dev
# 等同于如下两条命令
$ git branch dev # 创建分支
$ git checkout dev # 切换分支
$ git branch # 查看当前分支
假设,他人克隆了项目,本地默认只有master分支,若需在dev分支上开发,则需手动创建远程的dev分支到本地
$ git checkout -b dev origin/dev
快进模式
$ git checkout master # 切回主分支
$ git merge dev # 合并指定分支到当前分支
注意:这次合并是"快进模式"(Fast-forward),即直接把master指定dev的当前提交,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。
# 合并后,删除分支
$ git branch -d dev
补充:switch命令
# 创建并切换到新的dev分支
$ git switch -c dev
# 直接切换到已有master分支
$ git switch master
补充:丢弃分支
# 强行删除未合并的分支
git branch -D feature
普通模式
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
$ git merge --no-ff -m "merge with no-ff" dev
注意:因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
解决冲突
# 查看冲突文件
$ git status
# 查看冲突内容
cat filename.txt
# 手动修改分支上的冲突后再提交,然后合并到master
# 查看分支的合并情况
# 用git log --graph命令可以看到分支合并图
$ git log --graph --pretty=oneline --abbrev-commit
假设,与他人同时推送了同一个文件到远端,导致冲突,push失败。
# 抓取远端最新的提交并合并
# git pull
# git merge
# 若未指定本地dev与远端orgin/dev分支链接,则pull失败(no tracking information),解决办法:
$ git branch --set-upstream-to=origin/dev dev
现场储存、恢复
$ git stash # 将工作现场储存,等以后再恢复
$ git status # 此时查看工作区是干净的
# 比如要先去修复Bug,之后再恢复工作区
$ git checkout master
$ git checkout -b bugfix # 在主分支上新建bug分支
......
# 修复完成后add/commit/merge合并到主分支
# 回到dev分支继续工作
$ git checkout dev
$ git stash list # 显示暂存的工作现场
$ git stash apply # 恢复但不删除stash内容
$ git stash pop # 恢复并删除stash内容
# 若有多次stash记录
$ git stash apply stash@{0} # 选择要恢复的stash序号
虽在master上修复了bug,但dev上依然存在,快速解决办法:
复制提交到dev分支上
# 假设此时在dev分支上
$ git cherry-pick 4c805e2 # 将指定提交复制到当前分支并自动提交
切换、关联多个远程仓库
切换远程仓库
$ git remote -v # 查看当前的远程库连接信息
$ git remote rm origin # 删除现有远端连接
$ git remote add origin git@gitee.com:username/repositeryname.git # 添加新的远程仓库连接,命名origin
关联多个仓库
# 最好先删掉当前默认命名为origin的远端连接,重新添加并命名
$ git remote add github git@github.com:username/repositeryname.git
$ git remote add gitee git@gitee.com:username/repositeryname.git
# 如果要推送到Github
git push github master
.gitignore文件
在工作目录下创建.gitignore文件;
提交时,忽略文件内所描述的文件,编辑内容示例:
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:
db.ini
deploy_key_rsa
若某文件在忽略范围但仍想强制提交,可以:
$ git add -f filename.cnf
配置别名
$ git config --global alias.co checkout # checkout as co
$ git config --global alias.unstage 'reset HEAD'
$ git config --global alias.last 'log -1'
配置Git的时候,加上–global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中
$ cat .git/config # 查看当前配置信息
而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:
$ cat .gitconfig