git使用

官网

命令

1. 基本操作

设置提交代码时的用户信息

1
2
git config [--global] user.name "[name]"`
git config [--global] user.email "[email address]"

–global参数,表示这台机器上所有的Git仓库都会使用这个配置。

创建新仓库

1
git init

创建ssh key
本地Git仓库和github仓库之间的传输通过ssh加密的,远程服务器端需要添加ssh 公钥
默认在用户主目录下,生成.ssh目录,包含id_rsa和id_rsa.pub两个文件。id_rsa是私钥,id_rsa.pub是公钥

1
ssh-keygen  -t rsa –C "email@example.com"

克隆仓库

1
2
本地:git clone /path/to/repository 
远程:git clone username@host:/path/to/repository

关联本地仓库与远程仓库

1
git remote add origin <server>

查看远程仓库信息

1
git remote -v

远程仓库的默认名称是origin

查看状态

1
git status

添加改动到暂存区

1
2
git add <filename1> <filename2>
git add .

“.”表示添加所有文件、文件夹和子文件夹
提交到仓库

1
git commit -m "代码提交信息"

推送本地改动到远程

1
git push origin master

下载远程改动到本地

1
git fetch

合并拉取的代码

1
git merge

拉取远程最新改动并与本地合并

1
git pull

图形化查看提交与改动

1
gitk --all

2. 分支

假设准备开发新功能,需要两周才能完成,如果立刻提交,代码没写完的情况下,不完整的代码库会导致其他人无法继续开发;而等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
创建属于自己的分支,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
鼓励使用分支完成某个任务,合并后再删掉分支
创建分支

1
git branch feature_x

本地新建的分支如果不推送到远程,对其他人就是不可见的

切换分支

1
git checkout master

创建并切换

1
git checkout -b feature_x

查看当前分支

1
git branch

合并分支到当前分支
合并分支时,Git会优先用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

1
2
git merge <branch>
git merge --no-ff -m "merge with no-ff" <branch>

删除分支

1
git branch -d feature_x

-D : 强行删除没有被合并过的分支
删除远程分支

1
2
git push origin --delete [branch-name]
git branch -dr [remote/branch]

推送分支到远程仓库

1
git push origin <branch>

查看文件、分支差异
git diff命令,不指定filename时,列出所有文件

1
2
3
4
5
6
7
git diff <filename>						工作区和暂存区
git diff <branch_1> <branch_2> 两个分支
git diff --cached <filename> 暂存区和版本库最新版本
git diff --cached <commit> <filename> 暂存区和版本库指定版本
git diff <commit> <filename> 工作区和版本库指定版本
git diff HEAD -- <filename> 工作区和版本库里面最新版本(commit=HEAD)
git diff <commit> <commit> 版本库两个版本

其中<commit>支持下列方式:
HEAD 最经一次commit
HEAD^ 上一次提交
HEAD~100 上100次提交
版本号
列出分支

1
2
3
本地:git branch
远程:git branch -r
所有:git branch -a

3. 撤销修改与版本回退

查看提交历史

1
2
git log
git log --stat

用以回退
查看命令历史

1
git reflog

可以去未来
撤销工作区改动

1
git checkout -- <filename>

会使用 HEAD 中的最新内容替换掉你的工作目录中的文件。已添加到缓存区的改动,以及新文件,都不受影响。即回到最近一次git commit或git add时的状态

撤销暂存区修改

1
git reset HEAD <filename>

把暂存区的修改撤销掉(unstage),重新放回工作区

版本回退

1
2
3
git reset --hard HEAD^
git reset --hard HEAD^^
git reset --hard HEAD~100

3. 工作现场

隐藏工作现场

1
git stash

查看被隐藏的工作现场

1
git stash list

恢复工作现场

1
2
git stash apply
git stash pop 同时删除stash

删除stash

1
git stash drop

4. 标签

创建标签在当前commit

1
git tag 1.0.0 版本号

列出所有tag

1
git tag

删除本地tag

1
git tag -d <tagname>

创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除

推送标签到远程

1
2
git push origin <tagname>			推送一个本地标签
git push origin --tags 推送全部未推送过的本地标签

删除远程标签
先从本地删除,然后,从远程删除

1
2
git tag -d v0.9
git push origin :refs/tags/v0.9

5. 自定义Git

设置命令颜色显示

1
git config --global color.ui true

设置别名

1
git config --global alias.st status

场景

  1. 想要丢弃你所有的本地改动与提交,与远程最新改动保持一致
    可以到服务器上获取最新的版本并将你本地主分支指向到它:

    1
    2
    git fetch origin
    git reset --hard origin/master
  2. 已经在本地创建Git仓库,想在github创建相同的Git仓库,保证两个仓库远程同步(备份或远程协作)
    可以在远程创建空仓库,关联本地仓库与远程仓库,推送本地到远程

    1
    2
    git remote add origin <server>
    git push -u origin master
  3. 同一台服务器创建多个ssh key
    场景:有多个用户使用同一台服务器,均需要在服务器上拉取远程代码,因此服务器需要校验多个用户的ssh
    操作步骤:
    创建非全局用户A
    git config user.name "A"
    git config user.email "A@hotmail.com"
    生成A用户的ssh
    ssh-keygen -t rsa -C “A@hotmail.com”
    默认生成的文件名是id_rsa和id_rsa.pub,为方便其他用户生成属于自己的ssh,而A用户的不会被覆盖,生成的文件最好改名(例A_id_rsa, A_id_rsa.pub)
    为保证多个ssh可共同起作用,在.ssh文件下,新建config文件,配置多用户,文件格式为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #github Aemail@gmail.com
    host github.com #别名,随便定 后面配置地址有用
    Hostname github.com #要连接的服务器
    User A #用户名
    IdentityFile ~/.ssh/A_id_rsa #密钥文件的地址,注意是私钥

    #github Bemail@gmail.com
    host github.com
    Hostname github.com
    User B
    IdentityFile ~/.ssh/B_id_rsa
  4. ignore
    ignore可以设置提交时忽略的文件。
    如果想某被忽略文件提交,可以用-f参数强制提交
    如果某文件被忽略,但并不是本意,可能是规则写错了,可以用git check-ignore命令检查哪个规则写错

  5. 多人协作分支开发
    a. 当克隆远程仓库时,只能克隆master分支,假定需要多人同时在dev上开发,每个参与开发的人都需要在本地创建和远程分支对应的分支git checkout -b branch-name origin/branch-name
    b. 尝试用git push origin <branch-name>推送自己的修改;
    c. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并,提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
    d. 如果合并有冲突,则解决冲突,并在本地提交;
    f. 没有冲突或者解决掉冲突后,重新推送

  6. 对不同仓库指定不同的用户名和Email地址
    场景:同一个用户在电脑上需要从两个不同的git服务平台拉取,改动和提交代码,而这两个平台的用户名和密码都不同(例如,在电脑上想要同时push公司和github个人账号的代码)
    操作步骤:
    两个平台的账号可以视为两个用户,假设公司账号为A用户,github账号为B用户,即参照场景3可生成用户A和用户B的ssh,并配置config文件如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #公司 A@company.com
    host companyalias #别名,随便定 后面配置地址有用
    Hostname company.com #要连接的服务器
    User A #用户名
    IdentityFile ~/.ssh/A_id_rsa #密钥文件的地址,注意是私钥

    #github B@gmail.com
    host githubalias
    Hostname github.com
    User B
    IdentityFile ~/.ssh/B_id_rsa

    使用ssh的ssh-add命令将密钥添加到 ssh-agent 的高速缓存中,这样在当前会话中就不需要再次输入密码了
    ssh-agent bash
    //A账户的私钥
    ssh-add ~/.ssh/A_id_rsa
    //B账户的私钥
    ssh-add ~/.ssh/B_id_rsa
    //查看密钥列表
    ssh-add
    通过更改每个项目的.git文件夹的config文件,来定义该项目push的远程地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    [core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
    [user]
    email = A@github.com
    name = lapisy
    [remote "origin"]
    url = git@github.com:remoteurl/RecyclerViewSample.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
    remote = origin
    merge = refs/heads/master

    push时可能会碰到如下问题:

    1
    2
    3
    4
    5
    6
    remote: error: GH007: Your push would publish a private email address.
    remote: You can make your email public or disable this protection by visiting:
    remote: http://github.com/settings/emails
    To lapisy:Lapisy/RecyclerViewSample.git
    ! [remote rejected] master -> master (push declined due to email privacy restrictions)
    error: failed to push some refs to 'git@githubalias:remoteurl/RecyclerViewSample.git'

    url = git@github.com:remoteurl/RecyclerViewSample.git需要修改为
    url = git@githubalias:remoteurl/RecyclerViewSample.git
    config文件

    解决方法:登录github,settings–>emails,不勾选keep my email address private或者勾选block command line pushes that expose my email

  7. 开发新功能过程中(未开发完)需要修bug
    隐藏当前工作现场,此时查看工作区是干净的
    git stash
    确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支
    git checkout master
    git checkout -b issue-101
    修复bug,提交,切换到master分支,并完成合并,最后删除issue-101分支
    git add readme.txt
    git commit -m "fix bug 101"
    git checkout master
    git merge --no-ff -m "merged bug fix 101" issue-101
    回到dev分支继续开发
    git checkout dev