git 总结
- 配置 git
git 外观行为的控制变量通常存在于三个地方,/etc/gitconfig
,~/.gitconfig or ~/.config/git/config
,$PRJ/.git/config/
这三个文件可以以次被 git 的三个参数修改,git config --system
,git config --global
,git config --local/(OR NOTHING)
,当然也可以手动去修改之。
在运行 git 的时候最靠近执行命令的配置会覆盖之前的配置(比如命令行的会覆盖工程目录下的.git
)。
配置的用户名(git config user.name "jason"
),和联系的 email(git config user.email "xxx@xxx.com"
)
如果觉得 git 默认的编辑器(emacs)不好用,可以修改之(git config --global core.edit vim
)。
如果想查看 git 的所有配置信息(git config --list
)。 - 利用 git 管理现有工程
可以跳转到工程目录运行git init
。该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件。 - 查看当前工程代码管理状态
运行
git status
会显示当前分支,当前 HEAD 所指向版本的状态,如果工作目录中存在未跟踪的文件,status 将会将违背跟踪的文件或者目录以红色(默认)显示在Untracked files:
这行提示信息下。如果工程中相对于暂存去中的跟踪文件发生了变动,status 则会在Changes not staged for commit:
下提示发生变动的文件。如果工程中存在已加入暂存区中的内容(但未提交),则会在Changes to be committed:
下提示哪些文件正存在与暂存区,输出状态会以下面这几个关键词修饰文件所发生的变动,
new file, modified, delete
,这些修饰词的存在将非常方便的帮助我们管理我们的代码。但我过你觉得过于繁琐,可使用git status -s
,该命令可以一更加精简的方式输出状态信息。比如:$ git status -s M README MM Rakefile A lib/git.rb M lib/simplegit.rb ?? LICENSE.txt --- []M 表示修改了未加入暂存区 MM 历史修改已经加入暂存区,新修改内容未放入暂存区 M[] 历史修改已经加入暂存区 A[] 新增文件已加入暂存区 []A ?? 新添加的未跟踪文件
- 让 git 跟踪你和暂存工作中的内容
在 git 仓库下运行
git add file_path/dir_path
,如果你想仅仅暂存一个文件中的部分,可附加上--patch
选项,该选项会以交付的方式让你选择你想要的 patch。当然 git 也提供了一个更为直观方便的模式来进行这些操作(git add -i
)。 - 代码提交
如果只是输入简短的说明可以直接运行
git commit -m "comment"
, 如果想保留更加详细的信息则运行git commit
. - 克隆仓库
git 支持从文件路径,http/https, ssh-server 的方式克隆仓库,基本用法如下:
git clone dir_path
,git clone https://github.com/git/git.git
,git clone git@github.com:git/git.git
。 - 分支操作
查看当前工程检出的分支:
git branch
;查看所有分支:git branch -a
;删除本地分支:git branch -D branch-name
;删除远程分支:git branch -d -r origin/branch-name && git push origin:branch-name
;-a, --all List both remote-tracking branches and local branches. -r, --remotes List or delete (if used with -d) the remote-tracking branches. -d, --delete Delete a branch. The branch must be fully merged in its upstream branch, or in HEAD if no upstream was set with --track or --set-upstream. -D Shortcut for --delete --force.
找出两个分支的共同祖先
git merge-base branch_1 branch_2
。 - 查看工程中版本差异
查看已修改,但未暂存到目录中的改动
git diff
, 如果想查看已经加入暂存区但是还未提交的文件改动可使用git diff --staged
或者git diff --cache
,两者的效果是一样的。 - 拉取最新代码
git pull
(等价于git fetch && git checkout
)。 - 推送代码
git push
- 合并分支
git meger
正常情况下出现冲突时 git 默认只会显示被合并(ours)以及合并版本(otheirs)出现的冲突,而这里有个配置(
git config --global merge.conflictstyle diff3 # def:merge
)可以让你的 git 在产生冲突时在文件中标定出被合并版本(ours),合并版本的改动(others)以及两个版本的基(base)的改动。 - 暂存当前开发进度
git stash
- 子模块
git submode add url
- 回滚
git reset
- 工程清理
需要注意的是这个功能可能会清除你为暂存的开发工作,所以建议不要在开发目录下使用这些命令,我一般是在测试仓库中清除生成文件,或者引入的测试文件的时候才使用。
清除 untracked 文件:clean -f
;连同 untrack 的目录也一起清除:clean -fd
;连 ignore 的 untrack 文件目录也一起删掉:git clean -xfd
;clean 的-n
参数可以列举出将会被删掉的文件。
(还原)清除跟踪,但没有暂存的当前目录的文件:git checkout .
;
清除当前已经跟踪的做出改动的文件,(未跟踪的不会被删除)git reset --hard HEAD
;
清除一个已经加入到缓存区还未提交的文件:git reset filename && git checkout filename
。 - 设置类似于 Gitk / Github Graph 格式的提交记录查看别名
git config --global alias.las "log --all --tags --graph --pretty=format:'%Cred%H%Creset @%C(yellow)%d%Creset %n Author: %cn <%ce> %n Date: %cd %Cblue(%cr)%Creset %n %n Commit subject: %Cgreen%s%Creset %n'"
设置命令别名, 之后你可以用git las
查看到格式化后的分支情况 - 没有网络的情况下优雅的进行提交信息交换
git bundle create xxx.bundle
为当前分支打包, 加上--all
可以为所有分支打包, 同时你也可以从该 bundle 中提取工程,如git clone xxx.bundle
, 或者提取某个分支到本地git fetch xxx.bundle branch-in-bundle:local-branch-name
, 当然你也可以为单独的几个提交生成 bundle,如git bundle create xxx.bundle from-commit-id ^to-commit-id
- 提取历史提交某个文件的全部内容
git show commitid:file-path
使用该命令会将输出打印到终端,如果想导出到某个文件直接使用 shell 的管道操作符即可>
- 仓库拆分
准备待清楚仓库 REPO1, 最好是拷贝现有仓库,或者拉去一个全新的仓库
1. 首先跳转到待拆分仓库cd PATH_TO/REPO1;
, 调用git subtree split -P TARGET_DIR -b new_branch_name
将仓库中某个目录 ( TARGET_DIR ) 拆分到一个分支 ( new_branch_name );
2. 调用mkdir PATHTO/REPO2; cd PATHTO/REPO2; git init;
准备一个新的空仓库 REPO2;
3. 将分出去的提交拉取到当前仓库来:git pull PATH_TO/REPO1 new_branch_name
第一步还可以使用git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter TARGET_DIR -- --all
来处理, 其作用是过滤所有历史提交,只保留所有对指定子目录有影响的提交,并将该子目录设为该仓库的根目录。其中--tag-name-filter
控制我们要如何处理旧的 tag , cat 即表示原样输出;--prune-empty
删除空的(对子目录没有影响的)提交;--subdirectory-filter
指定处理的目录路径;-- --all
该参数必须跟在--
后面,表示对所有分支进行操作。如果你只想保存当前分支,也可以不添加此参数。 - 清除某个仓库某个目录下的内容和记录
准备待清楚仓库 REPO1, 最好是拷贝现有仓库,或者拉去一个全新的仓库
1. 调用git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch TARGET_DIR" --prune-empty TARGET_BRANCH
清除分支 TARGET_BRANCH 上和 TARGET_DIR 目录有关的痕迹
2. 调用mkdir PATHTO/REPO2; cd PATHTO/REPO2; git init;
准备一个新的空仓库 REPO2;
3. 调用git pull PATHTO/REPO1 TARGET_BRANCH
将清理好的提交拉取到 REPO2 中
git filter-branch 非常强大,具体请参考git filter-branch --help
- 清除远程分支
如果远程分支在远程仓库中已经不存在,执行git fetch -p/--pure
即可将本地远程分支清理干净
如果拥有删除远程分支权限,则可以使用git branch -d -r origin/branch-name && git push origin:branch-name
来删除本地和远程的分支 - 为目标仓库指定特殊私钥
方法一: 在~/.ssh/config
中加入目标 HOST 的配置。如:Host www.example.cn StrictHostKeyChecking no IdentityFile /home/username/.ssh/you.private.key.id_rsa
方法二: 编写一个GIT_SSH
脚本,其主要分为两步,第一步,编写一个获取 git 仓库的脚本,如:~/bin/getrepo.sh
, 第二步,设置环境变量GIT_SSH
,如GIT_SSH=~/bin/getrepo.sh
;#!/bin/sh exec /usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key "$@" # end of getrepo.sh
git log --oneline
该命令将提交信息凝聚成一行显示,便于总览既往历史-
git log --after="2020-15-05"
搜索自 2020-15-05 以来的提交信息,
git log --after="2020-15-05" --before="2020-25-05"
搜索 before 和 after 之间的提交信息,
同时 before 和 after 还接受如下形式的时间格式:
git log --after="yesterday"
,
git log --after="today"
,
git log --before="10 day ago"
,
git log --after="1 week ago"
,
git log --after="2 week ago"
,
git log --after="2 month ago"
-
git log -p
展示分支中每个提交的详细信息 -
git log --author="mojies.meng"
展示历史提交中该作者的每个提交 -
git log --grep="jira"
你可以通过--grep
从 commit 消息中过滤你想要的提交, 携带 -i 属性,你还可以忽略大小写,如git log -i --grep "JIra"
, 你甚至还可以使用正则表达式来构建你的过滤规则:如git log -i --grep "aa\|bb"
-
git log filename
只查看某个文件的改动 -
git log -S "main("
可以过滤历史提交的改动中包含某个字符串的提交, 加上-p
选项还可以查看详细改动信息 -
git log --merges
查看所有合并的请求 -
git log master..develop
或者git log develop ^master
可以查看在 develop 中,但是不再 master 中的改动, 同时该对比语法还可用于git diff
- [link] git 官方文档
![]() |
![]() |