Skip to main content

Git

Published: 2020-01-17 | Lastmod: 2020-03-03

配置 #

SSH Key

ssh-keygen -t rsa

这一步是生成了ssh的秘钥,可以建立本机与代码仓库之间的ssh链接来下载代码。
然后将~/.ssh文件夹下的id_rsa.pub文件里的文本内容,粘贴至代码服务器里面Settings --> SSH keys --> Add。

其他配置

git config命令实际上就是在修改仓库根目录下的.git/config文件。

配置git提交记录里的用户名和邮箱:

git config user.name "UserName"
git config user.email "Example@email.com"

Windows盘上的文件在Ubuntu下的文件模式发生了变化,导致git status时显示所有文件都有更改。 若要忽略文件模式的变化:

git config core.filemode false

当加上--global命令是,修改的是全局git配置,即~/.gitconfig

git config --global user.name "UserName"

重要命令 #

Branch

git checkout -b develop
git branch -d develop

tag

git tag
git tag v1.4-lw
git push origin v1.4-lw
git push origin --tags
git tag -d v1.4-lw
git push origin --delete <tagname>
git checkout v1.4-lw

Working Directory

假设当前有两个分支,masterdevelop,对应的在服务器上有origin/masterorigin/develop,此外还有一个指向当前commit的隐藏的HEAD

可以通过git status查看当前文件的状态:

  1. 当文件被修改时,会发现Working Directory里的文件名是红色;
  2. 运行git add .命令后,文件被添加到Index,此时文件名是绿色;
  3. 运行git commit命令后,HEAD指向新生成新的commit,此时origin/master落后于master
  4. 运行git push命令后,origin/mastermaster会同步起来,指向同一个commit。

stash

git stash
git stash list
git stash pop
git stash apply stash@{0}
git stash apply --index
git stash drop stash@{0}
git stash save "guacamole sauce WIP"
git stash apply stash^{/guacamo}

当编辑文件以后,Working Directory里面会有变红的文件名出现。若想暂时隐藏修改过的内容,可以用stash命令,将修改暂存起来,在之后需要的时候pop出来使用。

push

git remote add origin git@github.com:USERNAME/REPOSITORY.git
git remote set-url origin git@github.com:USERNAME/REPOSITORY.git

Send local changes in the current branch to its remote counterpart: git push
Send local changes in a given branch to its remote counterpart: git push remote_name local_branch
Publish the current branch to a remote repository, setting the remote branch name: git push remote_name -u remote_branch

cherry-pick

git cherry-pick f2e6f51

可以直接将某一特定commit追加到当前分支。

amend

git commit --amend

若上一次提交遗漏了某些文件,或者想修改commit msg,可以使用amend命令。

reset vs checkout

checkout只会移动HEAD,而reset则会将HEAD所指向的branch一起移动,如下图:

merge vs rebase

merge

git checkout master
git merge hotfix

由于iss53master的直接的前方,merge的时候会直接把master移动到跟iss53一起,此过程成为Fast-Forward。 而当iss53master分叉了的时候,会新建一个commit,将两者融合起来。

rebase

git checkout experiment
git rebase master

rebase可以得到一个更加干净的代码线,上面两句话等价于git rebase master experiment

git checkout master
git merge experiment

然后再把master分支merge到最新状态。

rebase的高级用法

git rebase --onto master server client

This basically says, “Take the client branch, figure out the patches since it diverged from the server branch, and replay these patches in the client branch as if it was based directly off the master branch instead.”

只要是server相关的都不要,剩下与client相关的都需要,追加到master上。

由此得到的变体:

删除连续的commit

1---2---3---4---5---master
1---2---5---master
git rebase --onto master~4 master~2 master

删除特定commit

git rebase --onto <commit-id>^ <commit-id>

将两个commit合并成为一个

git rebase -i HEAD~2

and then modify the second commit message from "pick" to "f"

其他技巧 #

Modify

修改git仓库里的用户名和邮箱信息 How to change the commit author for one specific commit?

git config user.name "Username"
git config user.email "Example@email.com"
git rebase -i -p --root // and then replace pick with edit
git commit --amend --author="Username <Example@email.com>" --no-edit && git rebase --continue
git push origin master -f

Compare

[diff]
	tool = meld
[difftool]
	prompt = false
[difftool "meld"]
	cmd = meld "$LOCAL" "$REMOTE"

~/.gitconfig 文件中添加上述配置以后,若要比较commit之间的文件差异, 可以采用如下命令打开meld对比工具进行整个工程中,有变化的文件进行可视化比较,非常方便。

git difftool -d b8de0b2 a532c05

改写服务器历史

git checkout --orphan temp f2e6f51
git commit -m "Truncated history"
git rebase --onto temp f2e6f51 master
git branch -D temp
git push -f origin master

git push -f会强制推送到服务器上,若推送失败,可能是该分支被保护了,一般在远程仓库的设置中可以取消保护: Settings --> Protected branches --> Unprotect


Next: Vim
Previous: GPS/INS组合导航