目录
此博客是根据:廖雪峰GIt教程、gitNotes_from_Liao编写。
参考网址:学习git网址、学习git网页——交互模拟、.gitignore文件相关。
安装Git
在不同系统上安装git
- Linux安装git:在终端输入如下命令即可安装
sudo apt-get install git
-
Mac OS X上安装git:自行百度。
-
Windows上安装git:从官网下载安装程序:git下载,然后选默认安装即可。
安装完成后还要进一步设置,进入git后,在命令行输入以下命令:
git config --global user.name "your name"
git config --global user.email "your_email@example.com"
git config --global user.name # 查看用户名称
git config --global user.email # 查看用户邮箱
git config -l # 查看所有配置信息
# 提交信息编辑器默认是vim
git config --global core.editor
# 输出:vim
# 可以修改:
git config --global core.editor "gedit -s"
git config --global core.editor "code -n --wait"
git config --global core.editor "subl"
注意:上面命令中的--global参数是指:你这台机器上的所有git仓库都会使用这个配置。
创建版本库
版本库即仓库,英文名repository。先找一个合适的地方,建一个空目录并进入该目录:
mkdir repository_name
cd repository_name
再通过git命令把这个目录变成git可以管理的仓库:
git init
基本git命令
添加文件到git仓库,分两步:
- 使用以下命令添加文件:
git add <file> git add -p <file> // 可以按逐个修改段提交
注意:可以反复使用此命令来添加多个文件。
-
使用以下命令提交文件:
git commit -m "message" git commit --amend --no-edit // 代码追加时使用此命令 git commit --amend -m "修改的信息" // 修改提交信息 提交信息换行(用双引号“ " ”) // 步骤一: 输入第一行 git commit -m "1. 第一行 // 步骤二: 按Enter 输入第二行 git commit -m "1. 第一行 2. 第二行 // 步骤三: 输入完毕,补齐引号,提交! git commit -m "1. 第一行 2. 第二行"
查看工作区或暂存区的状态:
git status
查看修改内容:
git diff <file> // 查看工作区和暂存区的区别
git diff --cached <file> // 查看暂存区和分支的区别
git diff HEAD -- <file> // 查看工作区和版本库中的最新版本的区别
git difftool -t meld -y HEAD // 使用meld工具比较工作区和上次提交的差异
git difftool -t meld -y branch1 branch2
git difftool -t meld -y commitId1 commitId2
git diff branch1 branch2 -- fileName // 查看某个文件在两个分支上的区别(用这个命令之前一定要注意:本地的这两个分支是否满足要求,比如是否是最新)
查看提交历史记录:
git log // 详细提交记录
git log --stat // 提交记录(修改文件名及简略信息)
git log --stat filename // 查看filename的修改情况
git log --name-status 每次修改的文件列表, 显示状态
git log --name-only 每次修改的文件列表
git log --author=usename // 查看usename的所有提交
git whatchanged 每次修改的文件列表
git whatchanged --stat 每次修改的文件列表, 及文件修改的统计
git show 显示最后一次的文件改变的具体内容
git show -5 显示最后 5 次的文件改变的具体内容
git show commitid 显示某个 commitid 改变的具体内容
git log --pretty=oneline // 简略提交信息
// 可以看到该文件相关的commit记录
git log -- filename (git log filename)
git blame filename + git show commit-id
git log filename + git show commit-id
git log --no-decorate // 不显示一些相关的信息,如HEAD、分支名、tag名等
版本回退:
git reset --hard HEAD^ // 回退到上一个版本
git reset --hard HEAD^^ // 回退到上上个版本
git reset --hard HEAD~100 // 回退到上100个版本
git reset --hard commit_id // 回退到版本号为commit_id的版本
git reset --hard commit_id // 回退到commit_id,并且本地文件也回退到那个状态
git reset --mixed(默认,可以不加) commit_id // 回退到commit_id,但是本地文件不会回退到那个状态,此时本地文件是未add状态
(当发现有个文件漏修改了,可以用这种方法重新提交,当然也可以用 git commit --amend --no-edit)
git reset --soft commit_id // 回退到commit_id,但是本地文件不会回退到那个状态,此时本地文件是add状态
(当发现有个文件漏提交了,可以用这种方法重新提交,当然也可以用 git commit --amend --no-edit)
查看命令记录:
git reflog
撤销修改(此处分三种情况):
- 被修改的文件还没有add:
git checkout -- <file> /* 把file文件在工作区的修改全部撤销:这里有两种状况: 一种是file自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态; 一种是file已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。 */
- 被修改的文件add了,但没commit:
git reset HEAD <file> // 先使用此命令将暂存区的修改撤销,变成add之前的状态 git checkout -- <file> // 再使用此命令撤销工作区的修改
-
被修改的文件commit了:参考上面的版本回退。
删除文件:
rm <file> // 删除file
git rm <file> // 将file文件从工作区、暂存区均删除
创建一个远程仓库:
ssh-keygen -t rsa -C "youremail@example.com" // 创建SSH Key
git remote add origin git@server-name:path/repo-name.git // 关联一个远程库
// add完远程仓库后,本地仓库并没有这个远程仓库的信息,此时需要 git pull branch_name 获取远程仓库的信息
git remote remove origin // 删除关联的远程库
git push -u origin master // 第一次推送master分支所有内容
//-u表示第一次推送master分支的所有内容
//此后,每次本地提交后,使用命令 git push origin master 推送最新修改
git push origin master --force // 强行推送分支到远程仓库,即使本地仓库比远程仓库版本低
git push origin master // 推送本地master分支内容到与远程相关联的分支(即便此时不在master分支也可以)
git push origin <source>:<destination> // 推送本地source分支内容到远程相的destination分支(即便此时不在source分支也可以)
// 其中 source 还可以是commit_id或其他表示位置的(例如:HEAD^)
// 如果远程没有destination分支,就会自动创建这个分支
// source为空(git push origin :<destination>)它会删除远程仓库中的分支!
git fetch origin foo // Git 会到远程仓库的 foo 分支上,然后获取所有本地不存在的提交,放到本地的 o/foo 上
git fetch origin <source>:<destination> // 和git push origin <source>:<destination>类似,但动作相反,不太常用
// fetch 为空(git fetch origin :<destination>),会在本地创建一个新分支。
从远程仓库克隆到本地:
git clone git@github.com:server-name/repo-name.git // 从github.com中克隆用户server-name下的repo-name.git仓库到本地
分支管理:
git branch // 查看分支,当前分支前面会标一个*号
git branch dev // 创建分支dev
git branch -a // 查看所有分支(包括远程、本地分支)
git branch -r // 查看所有远程分支
git branch -vv // 可以查看本地分支对应的远程分支
设置远程追踪分支的方法就是使用
git branch -u o/master foo // :这样 foo 就会跟踪 o/master 了。
//如果当前就在 foo 分支上, 还可以省略 foo:
git branch -u o/master
git branch -f branch_name commit_id // 让banch_name指向commit_id
git rebase branch_name // 将本分支和branch_name分支不同的提交(父节点后分叉的提交)建一个副本放到branch_name分支上,并将本分支的指针指向最后一个副本
git rebase branch_name1 branch_name2 // 将branch_name1分支和branch_name2分支不同的提交(父节点后分叉的提交)建一个副本放到branch_name1分支上,并将branch_name2分支的指针指向最后一个副本
git rebase -i commit_id // 进入交互式界面,将commit_id到HEAD的commit重新规划,具体见交互式界面得解释
git checkout dev // 切换分支dev
git checkout -b dev // 创建 + 切换分支dev
git merge dev // 合并dev分支到当前分支
git reset --merge // 合并分支时出现冲突,无法解决,可以使用此命令撤销合并
git branch -d dev // 删除分支dev
git branch -D dev // 强制删除分支dev,即使没有合并
git checkout 远程分支名 // 在本地创建一个和远程分支一样的分支,这种方式由于没有指定远程仓库名,所以当多个远程仓库都有这个分支时会有问题,此时可以用下面的方式来切分支
git checkout -t 远程仓库名/远程分支名 // 在本地创建一个和远程仓库名/远程分支名一样的分支
git checkout -b 本地分支名 远程仓库名/远程分支名 // 在本地创建一个和远程分支一样的分支(分支名可以不一样)
git log --graph // 查看详细分支合并图
git log --graph --pretty=oneline --abbrev-commit // 查看简略分支合并图
git merge --no-ff -m "description" <branchname>
/*
因为本次合并要创建一个新的commit,所以加上 -m 参数,把commit描述写进去。
合并分支时,加上 --no-ff 参数就可以用普通模式合并,能看出来曾经做过合并,包含作者和时间戳等信息,而fast forward合并就看不出来曾经做过合并。
*/
git merge commit_id // 将 commit_id及之前 提交的内容 merge 到当前所在的分支
git cherry-pick commit_id // 只将 commit_id 提交的内容 merge 到当前所在的分支,包括此次提交的作者、时间戳等信息
git branch -D branch_name // 强行删除没有合并过的分支
// 合并branch_name2分支到branch_name1分支(即使是几次提交也可以这样做),但有一个缺点,就是会删除原来提交者的提交记录和提交时间等信息
git merge --squash branch_name2 // 此时在branch_name1分支上,将branch_name2分支的修改全部合并。注意,这里使用了–squash,因此只是合并代码,并没有实际提交。还要继续进行下面操作。
git commit -m "message" // 这样,就把在分支里做的全部修改合并成一次提交。
git branch -D branch_name2 // 补充说明一点,这样合并了修改的内容,但 git 会认为没有进行 merge 操作,因此合并之后,使用下面的命令来强制删除分支branch_name2
“储藏”工作现场:
git stash // 保存当前分支的修改内容,此时可以前往另一个分支做别的修复工作
git stash -u //存储 untracked files
git stash -a // 存储 untracked files 和被版本库忽略的文件
git stash save "备注信息" // 添加一个 message 注解,可以使用 save 选项,如果需要-u,则在save后加
git stash list // 查看当前分支保存的内容
git stash apply // 恢复之前在本分支上保存的内容,但不删除此次的保存
git stash pop // 恢复之前在本分支上保存的内容,并删除此次的保存
git stash drop num // 删除num次的(num可选,没有则是最近的一次)的保存
git stash clear // 删除所有缓存的stash
git stash apply stash@{0} // 恢复指定的stash
标签:
git tag tag_name // 创建一个标签(默认为HEAD,也可以指定一个commit_id)
git tag tag_name commit_id // 在commit_id 上创建一个标签
git tag // 查看所有标签
git tag -l 1.2.* // 查看1.2.*模式的标签
git show tag_name // 查看标签信息
git tag -a tag_name -m "tag's message" commit_id // 创建标签并指定标签信息
git tag -d tag_name // 删除本地tag_name标签
git push origin tag_name // 将tag_name标签推送到远程
git describe 的语法是:
git describe <ref>
<ref> 可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。
它输出的结果是这样的:
<tag>_<numCommits>_g<hash>
tag 表示的是离 ref 最近的标签, numCommits 是表示这个 ref 与 tag 相差有多少个提交记录, hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
当 ref 提交记录上有某个标签时,则只输出标签名称
git push origin --tags // 将本地未推送的标签一次性推送到远程
// 当本地分支和远程分支都基于同一个父亲节点提交提交了内容时,此时git push会报错
// 此时可以先git pull 先将远程的修改拉下来,再git push,不过这样做,会在远程分支不是一条直线
// 可以使用git pull --rebase,再git push,这样远程分支就是一条直线
// git pull 就是 fetch 和 merge 的简写,类似的 git pull --rebase 就是 fetch 和 rebase 的简写
- 删除远程上的tag_name标签分两步:
git tag -d tag_name // 1、先删除本地标签: git push origin :refs/tags/tag_name // 2、再删除远程上的标签
删除未被追踪的文件:
git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...
# -d # 删除未跟踪目录以及目录下的文件,如果目录下包含其他git仓库文件,并不会删除(-dff可以删除)。
# -f # 如果 git cofig 下的 clean.requireForce 为true,那么clean操作需要-f(--force)来强制执行。
# -i # 进入交互模式
# -n # 查看将要被删除的文件,并不实际删除文件
git clean -n # 查看哪些文件将被删除
git clean -f # 删除当前工作目录下的未跟踪文件,但不删除文件夹(如果 clean.requireForce(默认为true) 为 false 可以不加 -f 选项)
git clean -df # 删除当前工作目录下的未跟踪文件以及文件夹
其他git命令:
git remote // 查看远程库信息
git remote -v // 查看远程库详细信息
git push origin branch_name // 从本地推送远程分支
git pull // 抓取远程的最新提交(自动合并),相当于(git fetch + git merge)
git pull remotename remotebranch // 从远程仓库的某个分支上更新代码到本地当前分上
git pull remotename remotebranch:localbranch // 从远程仓库的某个分支上更新代码到本地某个分上
git fetch // 从远程仓库获取最新版本,不会自动合并,git fetch 没有参数,它会下载所有的提交记录到各个本地的对应远程的分支……
git checkout -b branch_name origin/branch_name // 在本地创建和远程分支对应的分支
git branch --set-upstream-to=origin/branch_name branch_name // 建立本地分支和远程分支的关联
// 打包并应用patch
/*
法一:git diff生成的Patch兼容性强。如果你在修改的代码的官方版本库不是Git管理的版本库,
那么你必须使用git diff生成的patch才能让你的代码被项目的维护人接受。
对于git diff生成的patch,你可以用git apply --check 查看补丁是否能够干净顺利地应用到当前分支中;
*/
git diff branch-name > patch-name // 把当前分支和branch-name分支的不同的地方打包成一个patch-name,即便有多个不同也生成一个patch
也可以使用这个命令,将当前的修改内容打一个patch。
git diff -p > patch-name (-p参数也可以不加,因为默认是自动有-p参数的,应用这个patch-name的话使用gitapply patch-name就行)
git apply patch-name // 在当前分支应用这个patch-name
/*
法二:由于git format-patch生成的补丁中含有这个补丁开发者的名字,因此在应用补丁时,这个名字会被记录进版本库,显然,这样做是恰当的。
因此,目前使用Git的开源社区往往建议大家使用format-patch生成补丁。
如果git format-patch 生成的补丁不能打到当前分支,git am会给出提示,并协助你完成打补丁工作
*/
git format-patch -M branch-name // git format-patch的-M选项表示这个patch要和那个分支比对。现在它生成了一个patch文件。
git am patch-name // 在当前分支应用这个patch-name