git使用

2018/11/25 Tools 共 7128 字,约 21 分钟

首先要搞清楚下面几个概念

  • HEAD: HEAD就是指向当前分支当前版本的游标
  • Index/stage: Index即为暂存区,当你修改了你的git仓库里的一个文件时,这些变化一开始是unstaged状态,为了提交这些修改,你需要使用git add把它加入到index,使它成为staged状态。当你提交一个commit时,index里面的修改被提交。
  • working tree: 即当前的工作目录。

工作区域转换

img

from index to working directory: git restore --staged xx  or git reset commit/HEAD.
from head to index: git reset commit --soft 把去除的commit的changes恢复到stage了
modifed files from index to working directory: git co  

最基本的提交代码

Git add .
Git commit -m "xx"
Git push origin

分支创建

建立自己分支
Git branch newName
Git checkout newName 切换分支
可以直接git checkout -b newName创建并切换
查看当前分支 git branch

建立本地测试分支连到自己的远程分支使用

git checkout -b dev_mfl_test origin/dev_mafulong

分支删除

参考

删除分支:git branch -d <name>
查看远程分支:
git branch -a

使用命令,git branch -d Chapater8 可以删除本地分支(在主分支中)

使用命令 git push origin --delete Chapater6   可以删除远程分支Chapater6

分支更新

gl = git pull

远程最新的更新旧的本地

git pull origin
要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样 -
git pull origin next:master

在本地创建新的分支提交远程时,需要


git push --set-upstream origin dev_mafulong1

以后就可以 push 自己这个分支了

Git push origin 分支名
git push origin item_pack_mfl

当我想从远程仓库里拉取一条本地不存在的分支时:

git checkout -b 本地分支名 origin/远程分支名

这个将会自动创建一个新的本地分支,并与指定的远程分支关联起来。

git show 显示修改了啥

git show

一、新建代码库

在当前目录新建一个 Git 代码库 $ git init

新建一个目录,将其初始化为 Git 代码库 $ git init [project-name]

下载一个项目和它的整个代码历史 $ git clone [url]

二、配置

Git 的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

显示当前的 Git 配置 $ git config –list

编辑 Git 配置文 $ git config -e [–global]

设置提交代码时的用户信息 $ git config [–global] user.name “[name]” $ git config [–global] user.email “[email address]”

三、增加/删除文件

添加指定文件到暂存区 $ git add [file1] [file2] …

添加指定目录到暂存区,包括子目录 $ git add [dir]

添加当前目录的所有文件到暂存区 $ git add .

添加每个变化前,都会要求确认 对于同一个文件的多处变化,可以实现分次提交 $ git add -p

删除工作区文件,并且将这次删除放入暂存区 $ git rm [file1] [file2] …

停止追踪指定文件,但该文件会保留在工作区 $ git rm –cached [file]

改名文件,并且将这个改名放入暂存区 $ git mv [file-original] [file-renamed]

四、代码提交

提交暂存区到仓库区 $ git commit -m [message]

提交暂存区的指定文件到仓库区 $ git commit [file1] [file2] … -m [message]

提交工作区自上次 commit 之后的变化,直接到仓库区 $ git commit -a

提交时显示所有 diff 信息 $ git commit -v

使用一次新的 commit,替代上一次提交 如果代码没有任何新变化,则用来改写上一次 commit 的提交信息 $ git commit –amend -m [message]

重做上一次 commit,并包括指定文件的新变化 $ git commit –amend [file1] [file2] …

五、分支

列出所有本地分支 $ git branch

列出所有远程分支 $ git branch -r

列出所有本地分支和远程分支 $ git branch -a

新建一个分支,但依然停留在当前分支 $ git branch [branch-name]

新建一个分支,并切换到该分支 $ git checkout -b [branch]

新建一个分支,指向指定 commit $ git branch [branch] [commit]

新建一个分支,与指定的远程分支建立追踪关系 $ git branch –track [branch] [remote-branch]

切换到指定分支,并更新工作区 $ git checkout [branch-name]

切换到上一个分支 $ git checkout -

建立追踪关系,在现有分支与指定的远程分支之间 $ git branch –set-upstream [branch] [remote-branch]

合并指定分支到当前分支 $ git merge [branch]

选择一个 commit,合并进当前分支 $ git cherry-pick [commit]

删除分支 $ git branch -d [branch-name]

删除远程分支 $ git push origin –delete [branch-name] $ git branch -dr [remote/branch]

六、标签

列出所有 tag $ git tag

新建一个 tag 在当前 commit $ git tag [tag]

新建一个 tag 在指定 commit $ git tag [tag] [commit]

删除本地 tag $ git tag -d [tag]

删除远程 tag $ git push origin :refs/tags/[tagName]

查看 tag 信息 $ git show [tag]

提交指定 tag $ git push [remote] [tag]

提交所有 tag $ git push [remote] –tags

新建一个分支,指向某个 tag $ git checkout -b [branch] [tag]

七、查看信息

显示有变更的文件 $ git status

显示当前分支的版本历史 $ git log

显示 commit 历史,以及每次 commit 发生变更的文件 $ git log –stat

搜索提交历史,根据关键词 $ git log -S [keyword]

显示某个 commit 之后的所有变动,每个 commit 占据一行 $ git log [tag] HEAD –pretty=format:%s

显示某个 commit 之后的所有变动,其”提交说明”必须符合搜索条件 $ git log [tag] HEAD –grep feature

显示某个文件的版本历史,包括文件改名 $ git log –follow [file] $ git whatchanged [file]

显示指定文件相关的每一次 diff $ git log -p [file]

显示过去 5 次提交 $ git log -5 –pretty –oneline

显示所有提交过的用户,按提交次数排序 $ git shortlog -sn

显示指定文件是什么人在什么时间修改过 $ git blame [file]

显示暂存区和工作区的差异 $ git diff

显示暂存区和上一个 commit 的差异 $ git diff –cached [file]

显示工作区与当前分支最新 commit 之间的差异 $ git diff HEAD

显示两次提交之间的差异 $ git diff [first-branch]…[second-branch]

显示今天你写了多少行代码 $ git diff –shortstat “@{0 day ago}”

显示某次提交的元数据和内容变化 $ git show [commit]

显示某次提交发生变化的文件 $ git show –name-only [commit]

显示某次提交时,某个文件的内容 $ git show [commit]:[filename]

显示当前分支的最近几次提交 $ git reflog 八、远程同步 下载远程仓库的所有变动 $ git fetch [remote]

显示所有远程仓库 $ git remote -v

显示某个远程仓库的信息 $ git remote show [remote]

增加一个新的远程仓库,并命名 $ git remote add [shortname] [url]

取回远程仓库的变化,并与本地分支合并 $ git pull [remote] [branch]

上传本地指定分支到远程仓库 $ git push [remote] [branch]

强行推送当前分支到远程仓库,即使有冲突 $ git push [remote] –force

推送所有分支到远程仓库 $ git push [remote] –all 九、撤销 恢复暂存区的指定文件到工作区 $ git checkout [file]

恢复某个 commit 的指定文件到暂存区和工作区 $ git checkout [commit] [file]

恢复暂存区的所有文件到工作区 $ git checkout .

重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变 $ git reset [file]

重置暂存区与工作区,与上一次 commit 保持一致 $ git reset –hard

重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变 $ git reset [commit]

重置当前分支的 HEAD 为指定 commit,同时重置暂存区和工作区,与指定 commit 一致 $ git reset –hard [commit]

重置当前 HEAD 为指定 commit,但保持暂存区和工作区不变 $ git reset –keep [commit]

新建一个 commit,用来撤销指定 commit 后者的所有变化都将被前者抵消,并且应用到当前分支 $ git revert [commit]

暂时将未提交的变化移除,稍后再移入 $ git stash $ git stash pop

commit rebase多合一

git rebase -i head~2 //合并最近的2个commit
//之后把pick改成d

//终止
git rebase --abort

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1
C = A^2  = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

G-D-B-A 可以认为是主干,其他都是 merge 进来的其他分支节点。

A^表示 A 的第一个父提交,A^2 表示 A 的第二个父提交

A~1 表示 A 的父提交,A~2 表示 A 的父提交的父提交,相当于 A^^和 A^1^1

A~2^2 表示 A 的父提交的父提交的第二个父提交,即为 H

  1. “^”代表父提交,当一个提交有多个父提交时,可以通过在”^”后面跟上一个数字,表示第几个父提交,”^”相当于”^1”.

  2. ~n

    相当于连续的n个”^”.

git checkout 恢复文件

git co .

只能恢复非stage的文件。

git reset

Reset一词是指撤销修改。git reset 命令被用来重置更改。git reset 命令有三种核心调用形式。这些形式如下。

  • Soft
  • Mixed
  • Hard

Git Reset

git reset [--soft | --mixed | --hard] [HEAD]

–mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。

--mixed               reset HEAD and index 被抹去的commit的changes以及work directory的changes都会保留到work directory. 不会丢,只不过commit信息没了,修改都在。
--soft                reset only HEAD 被抹去的commit的changes会保留到stage, unstage的还是unstage,不会丢,commit信息没了
--hard                reset HEAD, index and working tree 被抹去的commit的changes没了,unstage的还在,还是unstage. 
git help reset

soft

  • unstage -> unstage 不影响
  • Staged -> staged 不影响
  • commited -> staged

mixed

  • staged -> unstage
  • commited -> unstage
  • unstage -> unstage

hard

  • starge -> 丢
  • commited -> 丢
  • unstage -> 丢

git 合并操作总结

参考

git merge

git merge 用来合并分支

把 feature 分支合到 master 分支

// 如果不设置第二个分支,默认是当前分支
$ git merge feature [master]`

有时候merge 后面会加上 --no-ff 或者 --ff-only 参数

-ff

ff 意思是 fast-forward, 使用 merge 时,默认会使用 fast-forward 的方式合并代码

如果合并的分支(master)是被合并分支(feature)的上游分支,则合并成功,不会产生 merge log,

如果合并的分支(master)不是被合并分支(feature)的直接上游分支(比如 master 在 checkout 出 feature 分支后,又进行了几次提交),不能使用 fast-forward 的方式合并代码,git 会进行一次三方合并(magic),如果合并成功,就会产生一个 merge log, 如果有冲突产生,则合并失败,需要解决冲突并 commit 后才能合并.

–no-ff

如果加上 --no-ff 参数,就是默认使用三方合并的方式合并,就算合并的分支(master)是被合并分支(feature)的上游分支,也会产生一个 merge log 这种做法的好处是,忠实地记录了实际发生过什么,关注点在真实的提交历史上面

–ff-only

与 --no-ff 相反,--ff-only 表示只接受 fast-forward 方式的合并,如果不能直接使用 fast-forward 合并,会合并失败并报错。

可以设置每次git pull 都rebase

git config pull.rebase true
全局:
git config --global pull.rebase true

git pull和push默认行为

参考

设置git pull和git push默认分支,也就是设置本地分支要跟进的分支。 建立当前分支的 upstream

$ git branch -u origin/dev
=>  Branch 'dev' set up to track remote branch 'dev' from 'origin'.

也可以

git branch --set-upstream-to=origin/one-branch one-branch`
 例如想把本地分支的 `feature-983` 跟进远程仓库的 `feature-983` 分支, 可以进行如下操作:
 `git branch --set-upstream-to=origin/feature-983 feature-983

查看对应关系

$ git branch -vv
=>  dev    32cf90b [origin/dev] e23rw
    master 9b04659 [origin/master] dadfa

$ cat .git/config
=> [branch "master"]
        remote = origin
        merge = refs/heads/master
   [branch "dev"]
        remote = origin
        merge = refs/heads/dev

git补丁 跨git repo操作

对于在两个不同的Git仓库之间复制更改,您需要将更改从一个仓库导出并导入到另一个仓库。以下是一种可能的方法:

  1. 导出更改: 首先,在第二个Git仓库中,导出您想要复制的更改。

    bashCopy code
    # 进入第二个Git仓库目录
    cd /path/to/second/repository
       
    # 创建一个补丁文件,记录commitB的更改
    git format-patch commitB_hash -1
    

    这将在第二个仓库的目录中创建一个补丁文件,其中记录了commitB的更改。

  2. 导入更改: 然后,在第一个Git仓库中,导入这些更改。

    bashCopy code
    # 进入第一个Git仓库目录
    cd /path/to/first/repository
       
    # 应用补丁文件
    git apply /path/to/patchfile.patch
    

    这将将补丁文件中的更改应用到第一个仓库中。请确保将/path/to/patchfile.patch替换为实际的补丁文件路径。

git reflog

git reflog 是 Git 中的一个非常有用的命令,用于查看仓库中的引用日志(reference logs),即分支、HEAD 和远程引用的移动历史。它可以帮助您恢复丢失的提交、分支或更改。

  • 恢复git reset导致的丢失。先reflog,找到reset前的hash。下面命令将移动分支的 HEAD 指针和工作目录回到 git reset 前的状态。

    git reset --hard hash
    

删除远程分支

Search

    Table of Contents