一. git 与 svn 的区别
- SVN 是集中式的版本控制,GIT 是分布式的版本控制;
- SVN 必须要联网才能工作,GIT 不需要联网也能工作,每个人电脑都是一个完整的版本库,安全性大大提高了;
- SVN 每次 push/pull 存储的是内容的变化,GIT 存储的是完整的文件(记录有变化的文件,且有相应的指针指向没有变化的文件)。
二. git 常用命令
- git init 把当前目录变成Git可以管理的仓库
- git status 时不时来两下查看当前状态
- git add 把文件从“工作区”添加到“暂存区”
- git commit -m "<msg>" 把文件从“暂存区”提交到“版本库”
- git log 显示从最近到最远的提交日志
- git reset --hard <commit_id> 把“版本库”和“工作区”都回退到当前ID号的版本
- git reflog 记录每一次命令,窗口关闭再打开都可以查询到
- git diff 比较“工作区”和“暂存区”的不同
- git diff --cached 比较“暂存区”和“版本库”的不同
- git diff HEAD 比较“工作区”和“版本库”的不同
- git checkout -- <file> 丢弃“工作区”的文件修改,回到最近一次 git commit 或 git add 时的状态
- git reset HEAD <file> 丢弃“暂存区”的文件修改,可以再通过上个命令彻底丢弃修改
- git rm <file> 删除一个文件,需要注意的是:先手动删除文件,然后使用 git rm <file> 和 git add <file> 效果是一样的,因为删除对git来说也是一次修改,所以可以用第11条命令撤消
三. git 远程仓库
- git clone git@server-name:path/repo-name.git 将远程仓库克隆到本地
- git remote add origin git@server-name:path/repo-name.git 关联远程仓库
- git push -u origin master 推送master分支的所有内容
- git push -f origin master 强制更新远端仓库,可用于远端仓库的版本回退
- git push origin <branch-name> 推送其他分支的所有内容
- git remote -v 查看远程仓库信息
- git pull 从远程仓库抓取最后的更新
四. git 分支管理
- git branch 查看分支
- git branch <name> 创建分支
- git checkout <name> 或者 git switch <name> 切换分支
- git checkout -b <name> 或者 git switch -c <name> 创建+切换分支
- git merge <name> 合并某分支到当前分支
- git branch -d <name> 删除分支
- git branch -D <name> 强行删除分支
- git log --graph 查看分支合并图
- git log --graph --pretty=oneline --abbrev-commit 更加简洁地,查看分支合并图
- git merge --no-ff -m "<msg>" <name> 合并分支时,建议加上 --no-ff 参数进行普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而 fast forward 合并就看不出来曾经做过合并
- git stash 暂存分支“工作区”中没有完成的内容,保持分支干净后便于切换分支修复其他bug
- git stash list 查看分支所有已暂存的“工作区”内容
- git stash pop 恢复分支所有已暂存的“工作区”内容
- git stash apply <stash_list_id> 恢复分支中特定 stash_list_id 的内容
- git stash drop <stash_list_id> 删除分支中特定 stash_list_id 的内容
- git cherry-pick <commit_id> 把分支上bug提交的修改“复制”到当前分支,避免重复劳动。切记操作前保证当前分支此时是干净的,否则无法复制
- git switch -c <branch-name> origin/<branch-name> 在本地创建和远程分支对应的分支,本地和远程分支的名称最好一致
- git branch --set-upstream <branch-name> origin/<branch-name> 建立本地分支和远程分支的关联
四. git 标签管理
- git tag <tagname> 新建一个标签,默认为HEAD
- git tag <tagname> <commit_id> 指定一个commit id,并在此处新建一个标签
- git tag -a <tagname> -m "<msg>" <commit_id> 创建带有说明的标签,用-a指定标签名,-m指定说明文字
- git tag 查看所有标签
- git push origin <tagname> 推送一个本地标签,到远程仓库
- git push origin --tags 推送全部未推送过的本地标签,到远程仓库
- git tag -d <tagname> 删除一个本地标签
- git push origin :refs/tags/<tagname> 删除一个远程标签
五. git 自定义配置
- git config --global alias.ac '!git add -A && git commit -m' 配置 ac 命令,增加并提交
- git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" 配置日志颜色
六. git 注意问题
- git 默认不区分大小写,可通过 git config core.ignorecase false 设置为区分大小写。
- 出现冲突时,首先解决冲突,然后添加并提交,最后推送到远程版本库中。
- 标签总是和某个commit挂钩,如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。
- git add . :添加已修改的(新增或修改)内容至暂存区(不含删除的文件),git add -A :添加本地所有修改的内容至暂存区(包含删除的文件),建议使用 git add -A 命令。
- git rebase 不建议使用,虽然 rebase 比 merge 看起来更加简洁,但是会打乱时间线,看不到完整的历史,而且中间如果出现失败会影响到文件的一致性。
- 切记不要再公共分支使用 rebase !因为往后放的这些 commit 都是新的,这样其他从这个公共分支拉出去的人,都需要再 rebase,相当于你 rebase 东西进来,就都是新的 commit 了。
- merge 与 rebase 之间最大的差别如下图示:merge 相当于1+1=2,生成新的提交V8;而 rebase 相当于 cherry-pick 的命令,将其复制到主线放在后面的同时将其变成一条基线。
-
需要注意的是,rebase 的重组不一定是分支复制到主线,也可能是主线复制到分支,而且会打乱原有的正常提交顺序,最后再变基的过程。