git 笔记

git 流程图

git 流程图

  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库

配置

语法:

usage: git config [<options>]

Config file location
    --global              use global config file
    --system              use system config file
    --local               use repository config file
    -f, --file <file>     use given config file
    --blob <blob-id>      read config from given blob object

Action
    --get                 get value: name [value-regex]
    --get-all             get all values: key [value-regex]
    --get-regexp          get values for regexp: name-regex [value-regex]
    --get-urlmatch        get value specific for the URL: section[.var] URL
    --replace-all         replace all matching variables: name value [value_regex]
    --add                 add a new variable: name value
    --unset               remove a variable: name [value-regex]
    --unset-all           remove all matches: name [value-regex]
    --rename-section      rename section: old-name new-name
    --remove-section      remove a section: name
    -l, --list            list all
    -e, --edit            open an editor
    --get-color           find the color configured: slot [default]
    --get-colorbool       find the color setting: slot [stdout-is-tty]

Type
    -t, --type <>         value is given this type
    --bool                value is "true" or "false"
    --int                 value is decimal number
    --bool-or-int         value is --bool or --int
    --path                value is a path (file or directory name)
    --expiry-date         value is an expiry date

Other
    -z, --null            terminate values with NUL byte
    --name-only           show variable names only
    --includes            respect include directives on lookup
    --show-origin         show origin of config (file, standard input, blob, command line)
    --default <value>     with --get, use default value when missing entry

实例

# 查看全局配置
$ git config --list --global
# 查看用户配置
$ cat ~/.gitconfig 
# 查看当前项目的 git 配置
$ cat .git/config

# 编辑Git配置文件
$ git config -e [--gl]

# 配置别名
$ git config --global alias.a "add ."

# 修改全局用户信息
$ git config --global user.name [用户名]
$ git config --global user.email [邮箱]

# 删除全局配置
$ git config --global --unset alias.xxx
$ git config --global --unset user.xxx

查看信息

# git 中 D 向下翻一行  F 向下翻页  B 向上翻页  Q 退出
# 查看所有 git 命令
$ git --help -a 
# 查看当前 HEAD 指向
$ cat .git/HEAD
# 显示有变更的文件
$ git status
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]
# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]..[second-branch]
# 查看两个 commit 的对比
$ git diff [commit1]..[commit2]
# 查看工作区和暂存区所有文件的对比,并显示出所有有差异的文件列表
$ git diff --stat   
# 注意:
# 1.你修改了某个文件,但是没有提交到暂存区,这时候会有对比的内容
# 一旦提交到暂存区,就不会有对比的内容(因为暂存区已经更新)
# 2.如果你新建了一个文件,但是没有提交到暂存区,这时候 diff 是没有结果的

# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]

# 查看本地 git 命令历史
$ git reflog

# 查看暂存区的文件
$ git ls-files

查看日志

# 显示当前分支的版本历史
$ 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 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
# 编辑器会弹出上一次提交的信息,可以在这里修改提交信息
$ git commit --amend
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]
# add和commit的合并,便捷写法(未追踪的文件无法直接提交到暂存区/本地仓库)
$ git commit -am [message]
# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
# 加入 --no-edit 标记会修复提交但不修改提交信息,编辑器不会弹出上一次提交的信息
$ git commit --amend --no-edit

git commit --amend 既可以修改上次提交的文件内容,也可以修改上次提交的说明。会用一个新的 commit 更新并替换最近一次提交的 commit 。如果暂存区有内容,这个新的 commit 会把任何修改内容和上一个 commit 的内容结合起来。如果暂存区没有内容,那么这个操作就只会把上次的 commit 消息重写一遍。永远不要修复一个已经推送到公共仓库中的提交,会拒绝推送到仓库

分支管理

#查看本地当前分支
$ git branch
#查看所有分支
$ git branch -a
#查看远程分支
$ git branch -r
#创建新分支 ,建议分支名规范:[项目名]-[日期]-[创建人]-[修改内容] 
#如:lagou-20171016-yangpeng-bugfix
$ git branch [分支名]
# 修改当前分支名
$ git branch -m [branchname]
# 查看当前commit属于哪个分支
$ git branch -r --contains [commit_id]

#切换分支
$ git checkout [分支名]
#创建并切换分支
$ git checkout  -b [分支名]
#取远程分支并分化一个新分支
$ git checkout -b test origin/master
# 切换到某个指定的 commit 版本
$ git checkout [commit_id]
# 切换指定 tag 
$ git checkout [tag]

# 合并指定分支到当前分支,一般在master上操作(需要有管理员权限)
#默认使用当前分支与 [branch] 合并,合并指定分支到当前分支
$ git merge [branch]
# 合并其他分支的某个文件到当前分支
$ git merge --patch [branch] [file.name]
$ git merge -p [branch] [file.name]
# 禁止快进式合并,会生成一个新的提交,让当前分支的提交历史不会那么乱
$ git merge --no-ff 
# 不会生成新的提交,会将被合并分支多次提交的内容直接存到工作区和暂存区,由开发者手动去提交,这样当前分支最终只会多出一条提交记录,不会掺杂被合并分支的提交历史
$ git merge --squash 
# 切换到上一个分支
$ git checkout -
# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]
# 删除分支
$ git branch -d [branch-name]
#强制删除分支
$ git branch -D [branch-name]
# 如果省略本地分支名,则表示删除指定的远程分支
# 因为这等同于推送一个空的本地分支到远程分支。
$ git push [remote] :[branch-name]
# 等同于
# 删除远程分支
$ git push [remote] --delete [branch-name]
$ git branch -dr [remote/branch]
#批量删除分支,| 管道,-E 使用正则表达式,xargs 将前面的值作为参数传入 git branch -D 后面
$ git branch -a | grep -E 't/xuwei/*' | xargs git branch -D

远程同步

# 下载远程仓库的所有变动
$ git fetch [origin]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]
# 删除远程仓库的 “关联”
$ git remote rm [shortname] 
# 设置远程仓库的 “关联”
$ git remote set-url origin <newurl>
# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
# 上传本地指定分支到远程仓库 (注:先执行git fetch [origin] ,)
#(注:分支提交前首先先建立联系 git branch --set-upstream [branch] [remote-branch] 
# 务必先与master合并 git checkout master ,git pull ,git checkout  [当前分支], git merge [master] ..)
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] --all
# 如果远程主机的版本比本地版本更新,推送时 Git 会报错,要求先在本地做 git pull 合并差异,
# 然后再推送到远程主机。这时,如果你一定要推送,可以使用 –-force 选项 
# (尽量避免使用)
$ git push --force origin | git push -f origin

标签tag

# 列出所有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]
# 删除所有本地tag,| 管道,xargs 将前面的值作为参数传入,-I {} 使用占位符 来构造 后面的命令
git tag | xargs -I {} git tag -d {}

撤销

# 恢复暂存区的指定文件到工作区
$ 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

submodule

# 新增submodule
$ git submodule add git@github.com:lib.git <local path>
# 初始化submodule
$ git submodule init
# 更新submodule
$ git submodule update
# 等价于 git submodule init && git submodule update
git submodule update --init
# 修改submodule后必须通过submodule命令提交后才能
# 同步到主工程中,否则git submodule update拉取的仍是之前的commit head
$ git push --recurse-submodules=on-demand

删除子模块较复杂,步骤如下:

rm -rf 子模块目录 删除子模块目录及源码
vi .gitmodules 删除项目目录下.gitmodules文件中子模块相关条目
vi .git/config 删除配置项中子模块相关条目
rm .git/module/* 删除模块下的子模块目录,每个子模块对应一个目录,注意只删除对应的子模块目录即可

执行完成后,再执行添加子模块命令即可,如果仍然报错,执行如下:

git rm --cached 子模块名称

自定义快捷命令

submodules的命令很长,为提升效率,可以创建alias,记录在.git/config路径下。如下:

git config alias.spush 'push --recurse-submodules=on-demand'
git config alias.supdate 'submodule update --remote --merge'

submodule的问题

submodule 实际上是从父仓库的目录树中独立出来的仓库,与父仓库的唯一联系是 submodule 签出的 SHA 值,这个 SHA 值存在父仓库的提交中。这个储存的 SHA 值的变动不会自动反映在 submodule 中。
然而,submodule 有许许多多问题。直接 Google「git submodules」,就能在搜索结果中看到很多 submodule 的问题。submodule 不会管理模块间的依赖关系,这是它的主要问题。还有其他一些问题,比如在父目录下 pull 不会自动更新 submodule。
另外,git 在解决冲突时不会保存 submodule 的指针。也就是说,如果没有手动更新指针,合并更改时会丢失已解决的冲突。在 submodule 提交后,父仓库中的 submodule 会是一个 detached head,因为它指向旧 head,而不是当前的 head。你猜怎么着?在父仓库或者 submodule 下 push,不会发布其他父仓库的改动。
有各种工具为 submodule 添加了额外的自动化,比如 git-subtree、gitslave、braid、giternal

自定义快捷命令

mac环境下vim ~/.zshrc, 添加自定义即可,例如下:

# user defined alias
alias work='cd ~/Documents/workplace && ls'
alias gt='git add . '
alias gl='git pull'
alias gh='git push'
alias gs='git status'
alias dev='npm run dev'
alias build='npm run build'
alias push='git add . && git commit -m "bugfix" && git pull && git push'

!> git命令可用 && 连接, 并列执行

git与svn的区别:

  • git分布式,本地就可做版本管理
  • svn必须依托远程仓库做版本控制

问题记录

fatal: Unable to create 'F:/HbuilderProject/projectModel/.git/index.lock': File exists.

解决:执行rm -f .git/index.lock (或者rm -f git/index.lock) 删除后正常

修改远程仓库

方法有三种:

  1. 修改命令
git remote set-url origin [url]
# 例如:git remote set-url origin gitlab@gitlab.chumob.com:php/hasoffer.git
  1. 先删后加
git remote rm origin
git remote add origin [url]
  1. 直接修改config文件

多人开发时,一人删除了一些无用的tag,push到远程仓库后,另一人pull下来后,使用git tag 1.10.8, git push -tags,后远程仓库又重新出现已经删除的tags

原因:似乎git目前也没有提供一个直接的命令和参数选项可以删除本地的在远程已经不存在的tag

解决方案:远程回退到原版,然后本地

#删除所有本地tag
git tag -l | xargs git tag -d 
#从远程仓库中重新拉取tag
git pull

为了避免之后再次出现这种情况,建议每次提交tag时不使用提交所有的tags命令: git push -tags ,而使用仅提交当前标注到tag命令: git push origin V-1.02.003 ,此外应当给当前tag添加附注 git tag -a V-1.02 -m “版本1.02”

遇到的一些问题

error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)

error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly

解决方案:

# 修改http版本
git config --global http.version HTTP/1.1
git push 
git config --global http.version HTTP/2
# 可能是数据文件太大,传不过去

git config --global http.postBuffer 157286400
# 清理项目git
git gc --prune=now

参考

常用 Git 命令清单:http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
Git远程操作详解:http://www.ruanyifeng.com/blog/2014/06/git_remote.html
Git 工作流程:http://www.ruanyifeng.com/blog/2014/06/git_remote.html

posted @ 2020-07-17 11:39  fanlinqiang  阅读(211)  评论(0)    收藏  举报