Git实操
使用git首先要理解工作区(working)、暂存区(stage或者index)、和版本库(repo区),很多命令都是和这三个概念相关的。
git init 初始化git仓库,会生成默认的.git文件夹,里面的内容是Git来跟踪管理版本库的,千万不能手动修改
git init [-q|--quiet] 初始化并且只打印错误和警告信息
git init --bare 生成一个空的仓库,这个用法比较难
git init --separate-git-dir 不指定则生成默认的.git的隐藏文件夹,如需自定义则带此参数,如C:\Users\cbm\Desktop\test_git,则会生成指定目录,里面的内容同样不能手动修改,同时会在当前目录下生成.git文件,里面的内容就是gitdir: C:/Users/cbm/Desktop/test_git
git init --shared[=(false|true|umask|group|all|world|everybody|0xxx)] 指定该仓库的用户权限,默认为group
git init --template=<template_directory>:指定目录里的模板将被使用,模板目录包含一些文件和目录,这些文件和目录将在仓库创建后被拷贝到.git文件夹下面
git add . 将所有修改添加到暂存区
git add * Ant风格添加修改
git add *.java 将以java结尾的文件的所有修改添加到暂存区
git rm --cached example.txt 从暂存区删除文件,即add的逆操作
git rm [-f|--force] example.txt 从暂存区和工作区删除文件,文件会被物理删除
git status 查看当前工作区的状态
git status -s --untracked-files=no 输出简单信息并且不显示未被跟踪的文件
git commit -m 'commit message' 提交已暂存的文件,即storage中的文件
git commit -a -m 'commit message' 先暂存已经被跟踪的文件,然后一起提交,未被跟踪的文件不会被提交
git commit --amend -m 'commit message' 把当前提交和上次提交合并为一次提交,上次提交<commit>会被覆盖掉,git log只能看到一次commit,但是修改的内容却不会被覆盖
git log 查看提交历史记录
git log <commit_id>..<commit_id> 查看指定版本区间(左开右闭)的提交log
git log <commit_id>^..<commit_id> 查看指定版本区间(左闭右闭)的提交log
git log --pretty=format:"%h - %an, %ar : %s"
下列是各个占位符的含义
git show <commit> 查看某一次提交的详细信息
git remote add origin git@github.com:littlechaser/learn-git.git 本地仓库与远关联
git remote 查看当前的远程库
git remote [-v|--verbos] 查看当前的远程库以及其远程url
git remote rename old_name new_name 重命名远程关联库
git remote remove origin_name 删除远程关联库
git remote prune origin 清除远程已经不存在,但是在本地依然显示的分支(更新本地显示,不会删除远程的分支)
git branch 列出本地分支
git branch -r 列出远程分支
git branch -a 列出本地以及远程分支
git branch <本地分支名称> 创建新的本地分支,但不切换分支,依然停留在当前分支,同git branch <本地分支名称> HEAD
git branch <本地分支名称> [<commit>|branchname] 从指定的提交或者分支创建新的分支,依然停留在当前分支
git branch [-d|-D] <branchname> 删除本地分支,-D表示强制删除
git branch [-d|-D] -r <branchname> 删除远程分支,远程并不会被真正删除,而是git branch -r不会显示该远程分支,如需强制删除参照push的用法
git branch (-m | -M) [<oldbranch>] <newbranch> 重命名分支,-M表示强制重命名
git branch [-v|--verbos] 查看分支的详细,包括最新的提交信息
git branch -vv 在-v的基础上,打印出跟踪的远程分支
git branch <本地分支名> origin/<远程分支名称> 创建新的本地分支,并与远程进行关联,即跟踪
git branch --track <本地分支名> origin/<远程分支名称> 完全同上
git branch --no-track <本地分支名> origin/<远程分支名称> 创建新的本地分支,不与远程关联
git branch --set-upstream-to=origin/<远程分支名称> <本地分支名> 将本地分支与远程分支进行关联,进行分支的跟踪,对比远程和本地的版本差距
git branch --set-upstream <本地分支名> origin/<远程分支名称> 功能同--set-upstream-to,不建议使用(Git高版本已过时)
git branch --unset-upstream <本地分支名> 取消本地分支与远程的关联,即取消分支跟踪
git push origin <本地分支>:<远程分支> 把本地分支提交到远程origin仓库
git push -f origin <本地分支>:<远程分支> 强制把本地分支提交到远程origin仓库,即强制覆盖
git push -u origin <本地分支>:<远程分支> 把本地分支提交到远程origin仓库,并且把本地分支与远程分支管理起来,即分支跟踪,跟踪了之后git push命令就能把当前分支的提交推送到远程跟踪的分支,而不需要带其他参数
git push origin master 把本地的master提交到远程origin仓库的master分支,省略了后面的:master,等同于git push origin master:master
git push origin :<远程分支> 省略本地分支名,删除远程分支,等同于git push origin --delete <远程分支>
git clone git@github.com:littlechaser/learn-git.git 克隆远程仓库到本地
git checkout <本地分支名称> 切换当前分支到指定分支
git checkout -b <本地分支名称> [<commit>|branchname] 从本地的指定提交拉取一个新的分支,并且切换到新的分支
git checkout -b <本地分支名称> origin/<远程分支名称> 检出远程分支名称称到本地,-b表示新建分支,此操作会默认将本地分支跟踪至远程(会显示本地与远程的版本差距),git config -l会看到有相关的跟踪配置增加
git checkout -b <本地分支名称> --track origin/<远程分支名称> 检出并跟踪,同上
git checkout --track origin/<远程分支名称> 同上,检出并跟踪,省略本地分支名,则会建立与远程同名的分支
git checkout -b <本地分支名称> --no-track origin/<远程分支名称> 检出不跟踪
git checkout --no-track origin/<远程分支名称> 同上,检出不跟踪,省略本地分支名,则会建立与远程同名的分支
git checkout -- file_nale 撤销指定文件工作区的修改
git checkout -- *.html 撤销工作区html文件的修改
git fetch origin 获取远程origin主机的所有分支的更新,但不把更新合并到当前分支,只是将其记录到.git/FETCH_HEAD文件中
git fetch origin <远程分支名称> 获取远程origin主机的指定分支的更新并记录到.git/FETCH_HEAD文件中
git fetch origin <远程分支名称>:<本地分支名> 获取远程分支最新的提交到本地新的分支(如果本地分支名称已存在则会报错),不会自动切换到新的本地分支,需手动checkout
git fetch [--prune|-p] origin 获取远程origin主机的所有分支的更新,并清除远程已不存在的分支的显示,相当于git fetch origin+git remote prune origin
git merge <分支名称> 合并指定分支到当前分支并自动提交,如果分支是远程的,需要先fetch
git merge --commit <分支名称> 同上
git merge --no-commit <分支名称> 合并指定分支到当前分支暂存区(冲突文件在工作区)但不要自动进行新的提交,当前分支仍处于merging状态,需手动commit(暂存区当然需要手动提交)
git merge --squash <分支名称> 合并指定分支到当前分支的暂存区(冲突文件在工作区)但不要自动进行新的提交,当前分支退出merging状态,并将多次commit进行压缩,减少凌乱的commit历史,git log看到的commit历史会变少,该命令需要手动commit
git merge --abort 合并存在冲突时,取消合并并将当前分支重建到合并之前,这个操作可能会无法还原合并前未提交的更改,所以合并之前最好是commit或者stash你的更改
git merge --continue 解决完冲突之后结束合并状态,退出merging状态,和解决完冲突commit后一样
git merge --ff --stat <分支名称> 以fast-foward模式合并(通常情况是你正在跟踪远程存储库,且本地有未提交的更改,现在需要将远程的版本更新到本地,在这种情况下,不需要新的提交来存储合并结果,git log看不到额外的commit,如果使用--no-ff则会创建一个新的commit来存储合并结果,git log可以看到该commit),并且合并完成后显示差异文件
git merge --no-ff --no-stat <分支名称> 以no-fast-foward模式合并(使用新的commit来存储合并结果),并且合并结束后不显示差异文件
git pull origin <远程分支名称>:<本地分支名> 取回远程主机指定分支的更新,再与本地的指定分支合并,可以理解为git fetch origin <远程分支名称>加上git merge FETCH_HEAD
git pull 如果当前分支已跟踪某个远程分支,则直接拉取远程分支的更新到本地,如果没有跟踪远程分支,则执行不成功并出现提示信息
git rebase <分支名称> 衍合,把目标分支合并到当前分支,与merge不同的是rebase强调的是对当前分支进行变基,什么意思呢,就是说你从master拉个dev分支进行开发,但是过阵子master分支已经被修改了,master的头tip已经不是你当前dev的祖先了,这时候你需要把master的代码拉到dev以保证你跟master同步,个人理解,与merge的区别是,merge一般是把一些本地的或者临时的分支往目标分支合并,而rebase则是获取目标分支最新的代码到本地分支或者临时分支,这通常在当本地的base被认为是在一个过时的base时才需要用它,一般都是rebase自己的私有分支,不建议rebase已经分享出去的分支,如远程分支。因为是“変基”的操作,所以commit的历史会有变更,当前分支的commit会在顶部,更新过来的commit会在前面,和commit的时间线无关
git rebase --abort 取消当衍合,存在冲突可使用
git rebase --continue 衍合冲突解决完毕后,继续完成衍合操作
git revert <commit> 恢复某次提交,注意revert的<commit>如果是merge的(比较特殊)则需要注意,由于revert是进行一次逆向的commit,所以之前的commit依然还在,当你之后再从你merge的分支合并到当前分支时,git记住你已经合并过了,所以相关的更改就无法合并过来了,会提示Already up-to-date,revert一定要理解,否则可能会导致代码丢失
git revert --no-commit --no-edit <merge commit> -m 1 撤销某次合并的提交且不自动提交、不跳出commit的编辑界面。merge节点查看log可以看到
commit 1805b1672a844d3e64120b60b70473fecbefdb77
Merge: d4066f1 830618f
Author: *** <***@**.com>
Date: Sat Apr 21 22:09:15 2018 +0800
Merge branch 'qa01' into qa02
类似的消息,-m 1表示撤销d4066f1(第一个commit)对应的parent的提交,-m 2表示撤销830618f(第二个commit)对应的parent的提交
git revert HEAD~3 丢弃最近的三个commit,把状态恢复到最近的第四个commit,并且提交一个新的commit来记录这次改变
git revert -n HEAD~5..HEAD~2 丢弃从最近的第五个commit(包含)到第二个(不包含),但是不自动生成commit
git revert --abort 恢复失败存在冲突时,撤销本次恢复
git revert --continue 恢复失败解决完冲突时,继续本次恢复,完成revert操作
git reset的--hard --mixed --soft参数区别:
hard:把working directory和index区的内容都重置为指定的commit 版本
soft:保留现在working directory和index区的内容,HEAD指向制定的commit 版本
mixed:保留working区的内容,将index区和HEAD内容都修恢复到指定的commit版本,该参数为默认参数
git reset --hard <commit> 清空当前本地所有修改,强制回到某一个指定的提交,即head指针指向指定的提交,生产环境慎用,会导致代码丢失
git reset HEAD~3 当前分支去掉最后的三次提交
git reset HEAD^ 回退版本,一个^表示一个版本,可以多个,另外也可以使用 git reset HEAD~n这种形式
git reset HEAD <file> 将暂存区的修改撤回至工作区,HEAD为默认值可省略,<file>也可省略,表示恢复暂存区所有文件
git cherry 查看当前未push的commit
git cherry -v 查看当前未push的commit详细信息(hash值以及提交描述)
git cherry-pick <commit> 把某一次提交应用到当前分支,并重写commit的hash值
git cherry-pick --edit <merge commit> -m 1 把某一次合并的提交应用到当前分支,-m参数参照revert解释
git cherry-pick <start-commit-id>..<end-commit-id> 把一个区间的提交应用到当前分支,左开右闭的区间(不包含左边的commit)
git cherry-pick <start-commit-id>^..<end-commit-id> 把一个区间的提交应用到当前分支,闭区间
git cherry-pick --abort 取消cherry-pick,冲突后可使用
git cherry-pick --continue 继续cherry-pick,冲突后解决完冲突,继续完成当前操作可使用
git stash list 查看当前贮藏列表
git stash clear 清空所有贮藏
git stash drop <stash> 删除指定贮藏
git stash 贮藏当前修改,一般用于清空当前工作区的修改但是不想彻底丢弃的情况。比如当前正在开发,但是需要切换到另外一个分支去修复紧急bug,可stash当前更改,改完bug后切回本分支再应用对应的stash即可恢复之前的更改
git stash save <message> 贮藏当前修改并指定贮藏信息
git stash apply <stash> 应用某个贮藏
git stash pop 应用最新的贮藏,并从list删除
git diff 显示当前工作区和暂存区的差异,更多参数运行git diff --help
git diff --cached 显示当前暂存区和repo区的差异
git diff --staged 显示当前暂存区和repo区的差异
git diff --stat 仅仅比较统计信息,修改多少文件,删除多少行,新增多少行等信息
git diff --name-only <commit1> <commit2> 仅显示commit1和commit2的差异文件的名称
git diff --name-status <branch a> <branch b> 仅显示a分支和b分支的差异文件的名称以及文件修改模式
git diff 比较的是工作区和暂存区的差别
git diff --cached 比较的是暂存区和版本库的差别
git diff HEAD 可以查看工作区和版本库的差别
git log 查看提交历史记录
生成sshkey
ssh-keygen -t rsa -C 'your_email'
测试sshkey是否配置成功
ssh -T git@github.com