GIT命令

GIT CONFIG

git config相关操作, 查看配置

# 查看仓库级的config,即.git/.config
git config --local -l
# 查看全局级的config,即/home/someone/.gitconfig
git config --global -l
# 查看系统级的config,即/etc/gitconfig
git config --system -l
# 查看当前生效的配置, 这个时候会显示最终三个配置文件计算后的配置信息
git config -l
# 有时候会看到重复的变量名,那就说明它们来自不同的配置文件(如/etc/gitconfig, ~/.gitconfig), 不过最终 Git 实际采用的是最后一个。

编辑和增加配置, 格式git config [--local|--global|--system] -add section.key value(默认是添加在local配置中) 注意add后面的section,key,value一项都不能少,否则添加失败

# 添加local配置, 这两个都会新增 user.name, 但是如果已经存在, --add会再增加一行, 而前者则是编辑原值; 如果已经存在两个记录, 前者会报错
git config --local user.name "someone"
git config --local --add user.email someone@somewhere.com
# 添加global配置, 同上
git config --global --add user.name tom
# 编辑local配置, 会打开一个vi编辑器
git config --local --edit

Update 20221023 保存用户名和密码, 或者缓存用户名和密码, 避免提交GitHub仓库时每次都去复制密码

# 设置为保存, 默认保存明文在用户home目录下 .git-credentials
git config credential.helper store
# 可以指定其它文件
git config --local credential.helper 'store --file ~/.another-credentials'
# 设置为缓存, 默认为15分钟, 可以修改, 用 --timeout 设置为 7200秒
git config credential.helper 'cache --timeout 7200'

设置代理

# on, http proxy
git config --global https.proxy https://user:password@address:port
# on socks proxy
git config --global http.proxy "socks5://127.0.0.1:1080"
git config --global https.proxy "socks5://127.0.0.1:1080"
# off
git config --global --unset http.proxy
git config --global --unset https.proxy
# info
git config --get http.proxy
git config --get https.proxy

也可以通过git config --global --edit命令打开编辑界面后直接填入以下内容, global的配置其实修改的是用户home目录下的.gitconfig文件

[http]
proxy = socks5://127.0.0.1:10080
[https]
proxy = socks5://127.0.0.1:10080

Update 20201216 在win10下,设置代理时不能带单引号,否则会报错,要使用双引号或不使用引号

git config --global http.proxy http://127.0.0.1:1081
git config --global https.proxy http://127.0.0.1:1081

忽略文件属性和Windows换行符

如果文件内容无变化, 但是出现在git status中, 大概率是因为文件权限有变化, 通过设置core.filemodefalse忽略

git config --local core.filemode false

忽略Windows换行符差异

git config --global core.autocrlf true

GIT CLONE

git clone相关操作, 如果在clone中需要递归初始化所有submodule, 需要加上 --recursive 参数

# 克隆远程仓库到本地, 不加本地目录则使用默认目录名
git clone http://git.somewhere.cn/someproject/somerepository.git [local_dir]
# 本地仓库中存在的远程仓库列表
git remote
# 显示出远程仓库地址
git remote -v
# 根据远程仓库名, 获取其最新文件
git fetch origin
# 更新(update)使用pull
git pull
# 查看远程仓库的详细信息
git remote show origin
# 查看本地仓库的文件状态
git status
# 查看标签列表
git tag

GIT BRANCH

分支相关操作

# 查看本地仓库中的分支列表
git branch
# 创建新分支 testing
git branch testing
# 切换本地仓库到testing分支(或testing标签, 命令一样)
git checkout testing
# 删除本地仓库分支 branch1
git branch -d branch1
# 强制删除本地仓库分支 testing
git branch -D testing
# 查看本地仓库各个branch对应的起始版本
git branch -v
# 查看所有分支
git branch -a
# 将本地的main分支的上游, 设置为origin/main
git branch --set-upstream-to=origin/main main

# 查看历史, 可以一直翻页
git log
# 查看指定目录的历史
git log -- dir/dir2
# 添加文件到版本库
git add commons/pom.xml
# 提交
git commit -m "commit top pom.xml"
# 将本地仓库的 master分支, push到远程仓库origin
# 可以把origin看成是url的别名
git push origin master
# 将本地仓库的 testing分支, push到远程仓库origin的branch1分支
# 可以把origin看成是url的别名
git push origin testing:branch1
# 使用远程仓库origin的branch1分支, 在本地创建分支并切换工作区间到这个分支上
# 注: 本地这个分支必须同名, 如果不同名会报错
git checkout -b branch1 origin/branch1
# 这样创建的分支, 今后往远程的提交就可以直接用 git push 了

以下是恢复代码原始版本, 清理本地所有修改

# Restore the removed files
git reset --hard
# Remove the local changes & untracked files&folders
git clean -f -x -d

提交前的批量操作

# 批量删除
git rm folder -rf
# 批量添加 所有有变更及未跟踪的, 使用 -A 或者 --all
git add -A
# 对批量添加的撤销
git reset
# 如果只是撤销某个文件
git reset somefile

合并特定的commit: 先checkout到master, 然后merge对应的commit id
being in master branch all you need to do is:git merge <commit-id>
where commit-id is hash of the last commit from newbranch that you want to get in your master branch.
如果需要合并dev分支最新的改动到master

git checkout dev
git pull
git checkout master
git merge dev
git push origin master

Update 2017-01-19 撤销本地未push到远端的commit
经常在开发中会碰到这种情况, 就是本地commit之后, 在push的时候发现, 已经有人push了同样功能的改动, 这时候最好把本地的commit撤销掉, 然后再跟上远端的版本, 就需要使用 git reset 这个命令, 一般用法

# 5a51663是恢复后所期望的HEAD
$ git reset --hard 5a51663
HEAD is now at 5a51663

Update 2017-09-22 撤销远端的commit

# 5a51663 是恢复后所期望的HEAD
$ git reset --hard 5a51663
HEAD is now at 5a51663
# 然后再使用git push --force
$ git push origin <分支名> --force

Update 2017-10-28

# clean的预处理报告, 告诉你哪些文件会被删除. 不会真正的删除文件
git clean -n
# 删除当前目录下所有没有track过的文件. 不删除.gitignore文件里面指定的文件夹和文件
git clean -f  
# 删除当前目录下没有被track过的文件和文件夹. 不删除.gitignore文件里面指定的文件夹和文件
git clean -df
# 删除当前目录下所有没有track过的文件. 不管是否是.gitignore文件里面的文件夹和文件.
git clean -xf
# 删除指定路径下的没有被track过的文件.
git clean -f <path>

# 让工作目录回退到最近一次commit
git reset --hard
git clean -f

GIT TAG 标签操作

列表

# 列出已有的标签
$ git tag
# 为了能及时看到远程上新增的标签, 在上面的命令之前可以fetch一下
git fetch --all --tags --prune
# 列出匹配的部分标签, 通配符 * 
$ git tag -l 'v1.8.5*'

查看

# 查看标签明细
# 通过-a 创建的标签, 使用git show 能看到标签的详细信息, 而轻量标签, 看到的只是对应的commit的信息
$ git show [tag name]

创建

# 创建轻量标签
$ git tag v1.4-lw
# 创建附注标签, 用 -a 代表为附注标签, 这时候必须带 -m 参数
$ git tag -a v1.4 -m '评论my version 1.4'

# 事后补打标签
$ git tag -a v1.2 [commit hash]

# 将指定的标签push到远程
$ git push origin v1.5

# 将本地有, 但是服务器上没有的的标签都push到远程
$ git push origin --tags

删除

# 删除本地标签
git tag -d V1.2

# 删除后, 将删除同步到远程(删除远程的标签)
git push origin :refs/tags/V1.2

检出

# checkout指定标签到本地的新分支
git checkout tags/${TAG} -b ${BRANCH_NAME}

# checkout一个临时分支, 用于查看, 不能修改
git checkout ${TAG}

# 在checkout前 fetch一下, 避免不同步
# --all will fetch all the remotes, 
# --tags will fetch all tags as well
git fetch --all --tags --prune

GIT SUBMODULE 子模块操作

常用操作

# 添加子模块, 最后一个参数为本地创建的用于放置子模块的目录
# 对子模块的操作要cd到子模块目录里, 命令是和普通git项目一样的
git submodule add <repository> <path>
git submodule add git://github.com/somewhere/some.git rack
 
# 在clone时一次性连子模块一起递归clone, 需要使用 --recursive 参数
git clone --recurse-submodules https://regository.git
# 导出后再初始化全部子模块, 在主项目根目录下执行
git submodule update --init
git submodule update --init --recursive
# 只导出指定的子模块, 后面加上这个子模块所在的目录
git submodule update --init 3rdparty/somemodule

# 查看子模块列表以及对应的版本, 如果子模块下还有子模块, 需要到子模块目录下再执行查看
git submodule status
# or
git submodule status
 
# 更新子项目
git submodule update --init --recursive
# or
git submodule foreach git pull

主仓库提交后, 子模块会停留在一个固定的版本号上, 如果要升级(或者更换)版本号, 需要到这个子模块的目录下, git checkout 到相应的版本, 这时候在主仓库下 git status 能看到子模块的变化, 在主仓库下 git add, git commit 就能把子模块固定到新的版本上

git submodule update --init --recursive
# 到子模块下checkout
cd libopencm3/
git checkout master
git checkout 72d40647442b264f2a84f23715c0513297b7dd07
# 如果子模块下还有子模块, 需要再init一次, 否则上层git status的时候会显示这层带 -dirty 后缀
git submodule update --init --recursive
# 回到主仓库
cd ..
git status
git add libopencm3
git commit -m "bumped version to 72d40647442b264f2a84f23715c0513297b7dd07"
git push

删除一个子模块的时候不能直接在文件系统里删除, 因为这样会被当成是对子模块的修改, 正确的操作包含以下三步(Git > 1.7.8)

#1 Remove the submodule entry from .git/config:
git submodule deinit -f path/to/submodule
#2 Remove the submodule repository from the superproject's .git/modules directory:
rm -rf .git/modules/path/to/submodule
#3 Remove the submodule directory located at path/to/submodule:
git rm -f path/to/submodule

如果需要在init后回退到未init的状态(即子模块目录为空), 不能直接在子模块目录里删, 正确的操作方式是: 先在git里删除模块 -- 从文件系统删除 -- 再在git里反删除模块. 即上面删除子模块的三步, 加上下面的恢复操作. git checkout -- 这个命令会让路径下的所有文件恢复到当前分支下最近一次commit的状态

# 先执行上面删除子模块的操作, 此时.gitmodules和 path/to/submodule都会在 staged 列表里, 先要restore
git restore --staged .gitmodules
git restore --staged path/to/submodule
# 然后恢复
git checkout -- .

GIT REVERT 回退错误的提交

可以用下面的命令, 回退指定的单个commit

git revert <commit_hash>

这个命令会创建一个新的commit, 用于回退指定的历史commit.

如果需要回退一个区间内的提交, 要用命令

git revert <oldest_commit_hash>..<latest_commit_hash>

这样会产生一个commit, 回退 oldest_commit_hash 至 latest_commit_hash 之间的所有commit. 在有些git版本中会包含 oldest_commit_hash, 有些不包含, 所以执行完之后要确认一下.

如果 git revert 有问题, 可以通过 git reset 取消

git reset --hard HEAD~

修改Git提交历史

在命令行, 通过git rebase -i [startpoint] [endpoint]进入界面选择要修改的commit, 在这个界面保存退出后, 紧接着在命令行通过 git commit --amend修改, 最后用 git rebase --continue 进入下一个修改或结束.

  • -i --interactive, 即使用交互式的界面让用户编辑完成合并操作,
  • [startpoint] [endpoint] 指定了一个编辑区间, 如果不指定[endpoint], 则区间终点默认是当前分支HEAD所指向的commit (注: 该区间是一个前开后闭的区间).
# 从最近的N个提交中选择(N可以是commit id)
git rebase -i N
 
# 或者, 从所有的提交中选择
git rebase -i --root
 
# 或者, 从指定的版本号之后进行选择
git rebase -i [commit id]
 
# 在上面的界面保存退出后, 仅修改用户名和邮箱, 不改内容
git commit --amend --author="Milton <milton@somewhere.com>" --no-edit
 
# 继续下一个修改或退出
git rebase --continue

要注意的是, 这个修改只是让git log展示的信息产生变化, 原来的提交信息, 还可以在 git reflog中看到, 每一次git rebase -i 中包含的越多, 在git reflog中留下的信息也越多, 因为每一个未修改的, 被pick的commit都会被记录
合并commit的话, 一般使用 s, squash -- 将该commit和前一个commit合并

关于push -u参数的说明

Push a branch and automatically set tracking

$ git push -u origin master
# pushes the "master" branch to "origin" remote and sets up tracking

“Tracking” is essentially a link between a local and remote branch. When working on a local branch that tracks some other branch, you can git pull and git push without any extra arguments and git will know what to do. However, git push will by default push all branches that have the same name on the remote. To limit this behavior to just the current branch, set this configuration option:

$ git config --global push.default tracking

This is to prevent accidental pushes to branches which you’re not ready to push yet.

Win10命令行下git log输出中文乱码

首先要设置好环境遍变量

git config --global core.quotepath false 
git config --global gui.encoding utf-8
git config --global i18n.commit.encoding utf-8 
git config --global i18n.logoutputencoding utf-8 
# bash 环境下
export LESSCHARSET=utf-8
# cmd环境下:
set LESSCHARSET=utf-8

然后要设置窗口的字体支持中文, properties->Font->Font选择仿宋或Yahei Mono

posted on 2015-07-21 20:09  Milton  阅读(396)  评论(0编辑  收藏  举报

导航