Git相关,常用Git命令…

SSH

1. 生成SSH秘钥,秘钥名字最好便于识别,例如用自己的名字,[keyname]=name
    ssh-keygen -f ~/.ssh/[keyname]
2. 查看公钥信息
    cat ~/.ssh/[keyname].pub
3. 将公钥信息粘贴到gerrit上,打开gerrit点击右上角的登录,使用员工账号与密码登录,登录后点击gerrit右上角用户名,点击弹出框左下的Settings,选择左侧的SSH Public Keys,将公钥信息粘贴进去点击Add。
4. 将私钥加到ssh-agent
    ssh-agent bash
    ssh-add ~/.ssh/[keyname]
5. 配置git
    git config --global user.name [fullname] 这个名字建议写全名
    git config --global user.email [email]  这个email填写你的邮箱
    git config --global color.ui true
    git config --global gui.encoding utf-8

设置git全局设置:

git config --global user.name "your_name" 
git config --global user.email  "your_email"

需要取消git的全局设置:

git config --global --unset user.name
git config --global --unset user.email

针对每个项目,单独设置用户名和邮箱,设置方法如下:

git config user.name "your_name" 
git config user.email "your_email"

测试连接

ssh -T git@github.com
ssh -T git@192.168.1.2

.gitignore无效的解决方法

在项目文件夹下打开git bash,执行

git rm -r --cached .DS_Store 这句代码的意思就是解除跟踪DS_Store,清缓存
// git rm -r --cached . 解除跟踪所有文件
git add .
git commit -m 'update .gitignore'

init

git init
git add .
git commit -m "init"

init后传至git仓库

git remote add origin git@github.com:wmszhe/PythonTools.git
git push -u origin master

日志

1.查询日志
git log
2.查指定文件的提交日志
1. 查看日志记录
git log --pretty=oneline .gitignore

2. 使用git show查看具体日志 --> git show <git提交版本号> <文件名>
git show 03bb009eb06b16c62155206b0e5724b532820efd .gitignore
3.查询某个人的提交日志
git log --author="author"

clone

git clone https://github.com/CharonChui/AndroidNote.git __AndroidNote(自定义的文件夹名)
git clone ssh://zhe.wang@192.168.0.119:29418/adclient -b gte

clone –depth

指定克隆深度,为1即表示只克隆最近一次commit.

git clone xxx --depth 1

如果我们之后要把之前的历史重新再 pull 下来

// 将浅克隆转换为完整克隆
git pull --unshallow
git fetch --unshallow

安装hook,目的是在提交信息中自动创建 ‘Change-Id:’ 标签

cd adclient
scp -p -P 29418 zhe.wang@192.168.0.119:hooks/commit-msg .git/hooks/

远程仓库

  1. 通过终端修改

查看远程仓库地址

git remote -v

修改远程仓库地址

git remote set-url origin git@github.com/xxx.git
  1. 修改项目下.git/config文件
[remote "origin"]
	# url = git@xxx
	url = git@github.com:xxx.git

查看分支

git branch 
git branch -a

切换分支

//本地无分支,加 -b ,相当于 git branch sdpost_dev ,git checkout sdpost_dev
git checkout -b sdpost_dev
//本地已有分支,直接切换
git checkout sdpost_dev
//checkout远端分支
git checkout -b develop origin/develop

从某个版本代码拉取新的分支

git checkout -b newbranchname xxxxx(commit id)

创建一个没有历史记录的新分支

git checkout --orphan new_dev
git add .
git commit -m "first commit"
// 发布到远端分支
git push origin new_dev:new_dev

修改分支名称

本地分支

git branch -m oldbranchname newbranchname

远程分支

将本地分支重命名为新分支名称,然后删除远程分支,再把本地分支上传

把新建的本地分支push到远程服务器,远程分支与本地分支同名(当然可以随意起名)

git push origin wz-jr:wz-jr
// 创建远端分支的另一种方式
git checkout -b my-test  //在当前分支下创建my-test的本地分支分支
git push origin my-test  //将my-test分支推送到远程
git branch --set-upstream-to=origin/my-test //将本地分支my-test关联到远程分支my-test上   
git branch -a //查看远程分支 

push所有分支

git push --all origin

更新分支信息

远程版本库创建了一个分支后,本地创建远程追踪分支

git remote update

在远程版本库上删除了某一分支,删除本地版本库上那些失效的远程追踪分支

方法一:

// -p, --prune    prune remotes after fetching
git remote update -p

方法二:

// 查看哪些分支需要清理
git remote prune origin --dry-run
// 清理
git remote prune

本地分支作为下游存在的话,还需要手动清理

git branch -d xx

删除分支

git branch -d gte
git branch -D gte(强制删除)

删除远程分支

git push origin --delete 分支名

恢复删除的分支

git reflog(找到想要恢复的分支的散列值)
git branch local-test HEAD@{2}

查看tag

git tag

查看tag详细信息

git show v1.0

添加tag

git tag v1.0

添加带备注的tag

git tag -a v1.0 -m "v1.0"

给指定的某个commit号加tag

git tag -a v1.0 9fceb02 -m "v1.0"

将tag同步到远程服务器

git push origin v1.0
git push origin --tags //推送所有tag

切换tag

git checkout v1.0

获取远程版本

git fetch origin tag V1.0

删除本地tag

git tag -d v1.0

删除远端tag

推送的空的同名版本到线下,达到删除线上版本的目标

git tag push origin :refs/tags/v1.0

查看状态

git status

commit

//直接填写提交日志
git commit -m 'commit log'

修改commit

git commit --amend

pull

git pull origin master
pull 错误 “You asked to pull from the remote ‘origin’, but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line.”

参考:Git远程分支和refs文件详解 问题在于没有给当前分支配置merge的路径,git不知道去merge哪个分支。

我们修改配置文件(.git/config)加入

[branch "wz-jr2"]
	remote = origin
	merge = refs/heads/wz-jr2

这意味着每次fetch origin的时候更新所有remotes/origin的头指针到refs/heads/下面

push

git push origin master
git push origin HEAD:refs/for/gte
//可提交到指定位置
git push //192.168.0.119/LocalShare/pengbo/adclient develop-post:develop-post

回退git

// !!! Windows下CMD中^是特殊字符,要使用时必须用双引号包括 (git reset <--soft||--mixed||--hard> HEAD"^")
// !!! 或者 git reset <--soft||--mixed||--hard> HEAD~1
git reset <--soft||--mixed||--hard> HEAD^ (回退到上一个版本) (HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100)
git reset <--soft||--mixed||--hard> xxxxxxxx (回退到指定版本)

远程版本回退

git push origin HEAD --force #远程提交回退

git回退到某一历史版本后再恢复到之前版本

git reset --hard xxx
git reflog (git log -g)
git reset --hard xxx

Your branch is behind ‘origin/wz-jr’ by 1 commit, and can be fast-forwarded.

is behind表示落后远程版本了,并且可以fast forwarded快速合并
使用git push origin wz-jr --force强制将代码推到服务器,--force使服务器不会拒绝这个更低版本的commit

撤销修改

git checkout -- file (命令git checkout -- file意思就是,把文件在工作区的修改全部撤销,这里有两种情况:一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。总之,就是让这个文件回到最近一次git commit或git add时的状态。)
git reset HEAD file (把暂存区的修改撤销掉(unstage),重新放回工作区)

回退指定文件到指定版本

git log /e/dev/adclient/app/src/main/AndroidManifest.xml
git reset a28887c24ed89938de7f769eb18b2555de790668 /e/dev/adclient/app/src/main/AndroidManifest.xml
git checkout -- /e/dev/adclient/app/src/main/AndroidManifest.xml

重新提交 amend

git add .
git commit --amend( --no-edit)
// git push origin gte
// git push origin HEAD:refs/for/gte
// 如果已经push到git仓库,amend后直接push会生成新的记录,需要--force-with-lease
git push --force-with-lease origin master(安全的强制推送)

暂存/恢复 stash

git stash(暂存)
git stash save "" (暂存)
git stash pop(apply last stash and remove it from the list)
git stash list()
git stash pop stash@{1}(取出指定的暂存,取出后会将对应的stash id 从stash list里删除)
git stash apply stash@{1}(取出指定的暂存,取出后会继续保存stash id)
git stash drop stash@{1}(删除指定的暂存)
git stash clear(将栈清空)

cherry-pick

// 将另一个分支上的一个提交合并到本分支
git cherry-pick xxxx(commit id)

// 合并多条
// <mark>注意,不包含xxx1</mark>
git cherry-pick xxx1..xxx10
// <mark>包含xxx1</mark>
git cherry-pick xxx1^..xxx10

// 继续合并 || 取消合并
git cherry-pick --continue || --abort

revert

git revert xxx
git commit
// git push origin gte
git push origin HEAD:refs/for/sdpost_dev

fetch/rebase

首先用git fetch返回服务器上的代码
用git rebase合并
    > 合并冲突
    > git add .
    > 用git rebase --continue继续没完成的合并
    > 重新提交git commit --amend
最后就可以用git push更新到服务器上去。
git pull --rebase origin develop-post(git pull --rebase = git fetch + git rebase)

取消本次rebase

git rebase --abort

git bisect 查找哪一次代码提交引入了错误

参考:git bisect 命令教程

它的原理很简单,就是将代码提交的历史,按照两分法不断缩小定位。所谓"两分法",就是将代码历史一分为二,确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。

// "终点"是最近的提交,"起点"是更久以前的提交
git bisect start [终点] [起点]

eg:
git bisect start 100 1

执行上面的命令以后,代码库就会切换到这段范围正当中的那一次提交,即50

如果没有问题,那么1-50之间是正常的,执行
git bisect good

那么Git就自动切换到后半段的中点,即50-100,即75

如果出现问题,那么50-75之间有问题,执行
git bisect bad

Git就自动切换到第50次到第75次的中点(第63次提交)

重复执行上述操作,直到成功找到出问题的那一次提交为止,Git 会给出如下的提示

xxx is the first bad commit

查出问题后,执行
git bisect reset

退出查错

现在就可以开始修复错误了。