**git** 使用笔记

96
神刀
0.3 2018.01.05 10:29 字数 4930

git 使用笔记

git原理:

文件(blob)对象,树(tree)对象,提交(commit)对象

tree对象 : {指针,权限模式,类型,文件名}

commit对象: {上层tree指针,作者,时间戳,上次提交对象id,注释} 可通过git log 获取

文件对象blob:{文件内容}

  1. Git保存文件完整内容。
  2. 储键值对key-value。
  3. 文件的不同版本,都有一个(40位)的 SHA-1校验和与之对应。
  4. SHA-1 校验和是文件的指针,Git依靠它来区分文件。
  5. 每一个文件都会在Git的版本库里生成blob对象来保存。
  6. 对于没有变化的文件,Git只会保留上一个版本的指针。
  7. Git实际上是通过维持复杂的文件树来实现版本控制的。
  8. 使用Git的工作流程基本就是就是文件在三个工作区域之间的流动。
  9. 应该大量使用分支进行团队协作。
  10. 分支只是对提交对象的一个引用。

SHA-1 校验和:

是文件指针,每个文件不同版本都有一个指针对应

分布式版本控制

默认分支是master,存储在.git\refs\heads\master文件中

引用就是SHA-1 校验和的别名,存储在.git/refs文件夹中

引用master,Git默认创建的始终指向你项目主分支的最后一次提交记录

创建分支只是copy一份引用,非常轻量,只有commit提交操作是重量的

git commit 文件改变 生成新的blob对象 存入一份新的文件快照

git commit 文件未改变 存入上一版本的文件指针

当前分支的最后一次的提交ID cat .git/HEAD

tag指向一个commit对象,固定不变的。

存储键值对(key-value)

工作目录,暂存区域,以及本地仓库

已提交(committed),已修改(modified)和已暂存(staged)

git config 配置

换行符问题:

Windows(\r\n)、Linux(\n)和MacOS(\r)三个系统的换行符不同,在跨平台合作的时候就会出现换行符的问题。 Git 提供了 autocrlf 和 safecrlf 两个参数来解决这个问题。

例如,出现这种情况: A和B两个开发人员,A使用LF(\n)做换行符,B使用CRLF(\r\n)做换行符,且都没有开启 autocrlf 参数,那么A在迁出B的文件,并使用自己的编辑器打开之后就会发现,虽然没有对文件做任何修改,但它的状态是modified。这是由于A的编辑器自动将B的文件中的所有换行符替换成了(LF),这与版本库中的(CRLF)不同。

autocrlf

git config --global core.autocrlf true # 签出时将换行符转换成CRLF,签入时转换回 LF。

git config --global core.autocrlf input #签出时不转换换行符,签入时转换回 LF

git config --global core.autocrlf false #签出签入均不转换

safecrlf

如果你把换行符搞乱了,在一个文件中既包含windows风格的换行符也包含unix风格换行符。

git config --global core.safecrlf true # 拒绝提交包含混合换行符的文件

git config --global core.safecrlf false # 允许提交包含混合换行符的文件

git config --global core.safecrlf warn # 提交包含混合换行符的文件时候给出警示

问题描述

项目组现在用git做版本控制,使用中遇到不同平台下换行符不同造成的问题,windows下的换行符为crlf,linux和MAX OS 下换行符是 lf。linux和MAX os就按说明设置为core.autocrlf input(貌似是默认值),windows设置为core.autocrlf true。可是有时候还是会遇到换行符的问题。review的时候就会发现有的commit的变化是所有行都被删除重建

解决方案:

  1. 无论什么系统,把所有人的编辑器的换行符模式设置成Unix格式,然后把autocrlf设置成false。

  2. 修改git设置 core.autocrlf=input.检出时不转换,提交转换为lf,这样可以避免提交windows换行符的情况;

  3. 修改eclipse设置 windows>General> workspace 下 new text file line delimiter 选择Unix。

  4. 已有的项目可能已经存在换行符不同的问题需要修正一下。 如果当前开发有多个分支且各分支不同步,需要每个分支进行一次转换:选中项目 file> convert line delimiter to > Unix ,创建新的commit; 如果只有一个分支或多个分支处于同一节点。可以从master切换一个新分支,进行第2步的修改操作,然后commit ,将此分支合并到所有分支。

  5. 将修改过的分支push到gitlab,其他成员更新代码即可。 (ps:由于每个人系统不同或者就是git的问题,可能出现更新完代码换行符不变,这时以服务器上的代码为准重新clone一份最新代码即可)

.ignore文件

*.html #忽略所有html

!foo.html # 不忽略foo.html

*.[oa] # 忽略所有.o和 .a文件

dbg # 忽略dbg文件和dbg目录

dbg/ # 只忽略dbg目录

!dbg/ #不忽略dbg目录

/dbg # 只忽略当前目录下的dbg文件和目录,子目录的dbg不在忽略范围内

错误解决方案:注意带sudo

git Please move or remove them before you can merge. 错误解决方案

git clean -d -fx ""

x -----删除忽略文件已经对git来说不识别的文件

d -----删除未被添加到git的路径中的文件

f -----强制运行

修改git commit 提交

  1. 没有git push : git commit --amend参数
  2. 已 git push :

git commit --amend改写单次commit

git rebase -i <commit range>删改排以及合并多个commit

git checkout <commit> -- <filename>获取历史版本的某个文件

git reset [--hard] <commit>移动HEAD指针

git revert <commit>创建一个回退提交

git push -f <remote> <branch>强制push,覆盖原有远程仓库

https://github.com/uolcano/blog/issues/12

git pull****失败当本地commit一个提交和远端服务器中的代码有冲突(别人也改了相同的文件)时

git pull --rebase

  1. 把本地 repo. 从上次 pull 之后的变更暂存
  2. 恢复到上次 pull 时的状态
  3. 合并远端的变更到本地
  4. 最后再合并刚刚暂存下來的本地变更

git rebase 合并

rebase的时候,修改冲突后的提交不是使用commit命令,而是执行rebase命令指定 --continue选项。若要取消rebase,指定 --abort选项。

$ git add myfile.txt

$ git rebase --continue

git stash 保存工作区

保存:git stash 保存当前操作 git stash save “msg”

查看:git stash list

恢复: git stash apply <stash@{num}>,默认恢复上次操作,不删除stash内容;恢复指定序号<stash@{num}>;

git stash pop <stash@{num}>,默认恢复上次操作,同时删除stash内容;恢复指定序号的操作<stash@{num}>

删除: git stash drop <stash@{num} > 默认删除上次记录;删除指定记录<stash@{num}>

git stash clear 清空所有记录

git diff

git diff HEAD^^ HEAD main.c //两个提交之间查看文件" main.c"的差异

你还可以在两个不同版本中比较两个不同的文件,如下所示:

git diff <revision_1>:<file_1> <revision_2>:<file_2>**

git 远程操作 5个命令

  1. git clone git clone -o <参数-o命名远程主机> <版本库的网址> <本地目录名>
  2. git remote 改名:git remote rename <原主机名> <新主机名> 添加远程主机:git remote add <主机名> <网址> 查看详情:git remote show <主机名>
  3. git fetch 取回远程分支更新: git fetch <远程主机名> <分支名>
  4. git pull git push <远程主机名> <来源地>:<目的地>
  5. git push

git tag 标签(打在HEAD指向的commit里)

轻标签(名称) 本地临时使用 git tag <tagname>

注解标签(名称,注解,签名) 发版使用

git tag

git tag stable-1 1b2e3f

git tag [-a|-s|-u] stable-1 1b2e3f

git tag -a <tagname> -m “选项来添加注解”

git tag -am注解”标签名

如果在tag命令指定-n选项执行,可以显示标签的列表和注解

BASIC

git add files 把当前文件放入暂存区域

git commit 给暂存区域生成快照并提交

git status 查看状态 gst

git diff 对比工作区与版本库内容

git log 查看所有commit记录

git reflog 查看所有操作记录

git checkout xxx 切换到xxx分支

git branch 查看分支

git checkout -b xxx 创建并切换到新分支

git merge xxx 合并xxx分支到当前

git branch -d xxx 删除xxx分支

git diff HEAD -- <文件名> 对比工作区和版本库最新版本的修改

修改回退:

git reset HEAD <文件名> 退出暂存区 修改保留

git checkout -- <文件名> 没git add 拿暂存区替换;已git add拿版本库替换

git reset –hard HEAD^ 回退上一版本(本地源码一起改变)

git reset --hard commitID 回退到指定版本

撤销git add

git reset --mixed 版本回退,所有文件退出暂存区,但是修改保留

git reset <文件目录>/ 撤销目录

git reset –soft:修改保留在暂存区,如果还要提交直接commit即可

git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容

git reset 提交层面 在私有分支上舍弃一些没有提交的更改

git reset 文件层面 将文件从缓存区中移除

git checkout 提交层面 切换分支或查看旧版本

git checkout 文件层面 舍弃工作目录中的更改

git revert 提交层面 在公共分支上回滚更改

git revert 文件层面 (木有

删除文件

git rm <文件名> && git commit -m 从版本库删除 (git rm 从暂存区删除)

git checkout -- <文件名> 从版本库恢复

其他操作

git reset -- files 撤销最后一次git add files,git reset撤销所有暂存区文件

git checkout -- files 从暂存区域复制到工作区,丢弃没有git add的修改

git commit -a 相当于git add + git commit

git commit files

git checkout HEAD -- files 回滚到复制最后一次提交

远程操作

git clone <库地址> 克隆远程库到本地

git remote -v 列出关联的远程主机

git remote add <库名><库地址> 关联远程库

git remote rm <库地址> 取消远程库关联

git push :gh-pages 删除远程分支(原理:推送空白分支覆盖)

git remote rename <原名> <新名> 参数rename,远程库改名

git fetch <远程主机名> <分支名> 拉取远程库更新

git branch -r <远程主机名> <分支名> 查看远程分支

git branch -a 查看所有分支(包括远程分支)

git pull <远程库名> <远程分支名>:<本地分支名> 取回远程主机某个分支的更新,再与本地的指定分支合并

git push <远程库名> <本地分支名>:<远程分支名>

git push origin dev:dev_branch // 推送本地dev分支到远程dev_branch分支

在命令行上创建新的存储库

echo“#LargeScreen”>> README.md

git init

git add README.md

git commit -m“first commit”

git remote add origin git@github.com:qiansr/LargeScreen.git

git push -u origin master

从命令行推送现有存储库

git remote add origin git@github.com:qiansr/LargeScreen.git

git push -u origin master

git reset --soft HEAD^

终极恢复

git reflog 显示整个本地仓储的commit(所有branch,包括已撤销的commit

git log 只包括当前分支的commit.

git reflog --relative-date 显示相对时间的commit纪录

分支

git branch 查看分支

git branch <分支> 创建分支

git checkout <分支> 切换到分支

git checkout -b <分支> 创建+切换分支

git merge <分支> 合并分支到当前分支

git branch -d <分支> 删除分支

git branch -D <分支> 强行删除没被合并的分支

git merge --no-ff -m "" dev merge时会生成一个新的commit

分支策略

master分支 发布新版本

dev分支 每个人都有自己的分支,往dev分支上合并

—no-ff参数 用普通模式合并,能看出曾经做过合并

fast forward合并 看不出来曾经做过合并

Bug****修复

首先,隐藏当前工作现场

git stash

确定要在哪个分支上修复****bug****,就从那个分支创建临时****bug****分支

$ git checkout master

$ git checkout -b issue-101

修复****bug****,然后提交

$ git add readme.txt

$ git commit -m "fix bug 101"

切换到****master****分支,完成合并,最后删除****bug****分支

git checkout master

git merge --no-ff -m "merged bug fix 101" issue-101

最后回到****dev****分支干活

$ git checkout dev

工作流程模式:

  1. 首先,可以试图用git push origin branch-name推送自己的修改
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并
  3. 如果合并有冲突,则解决冲突,并在本地提交
  4. 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

注意:

如果git pull提示“no tracking information”,则用命令git branch --set-upstream dev origin/dev 创建本地分支和远程分支的关链。

查看远程库信息,使用git remote -v;

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

标签管理

Git的标签是版本库的快照,它指向某个commit的指针。发布一个版本时,先打一个版本标签,这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。

git tag git tag用来为某个提交创建一个轻量级标签

$git tag stable-1 1b2e3f

如果想为标签添加注释,那么需要创建一个标签对象。创建标签对象后,一个对象就会被添加到git对象库中,然后标签指向这个对象

$git tag [-a|-s|-u] stable-1 1b2e3f

签名的标签

git config user.signingkey

git diff $git diff [--cached]

--cached参数只显示将要被提交的改变

$git diff branch1..branch2

比较两个分支

$git diff HEAD

比较当前工作目录和上次提交(HEAD)

$git diff file

比较file在当前工作目录和上次提交

[--stat] 统计数据

git pull $git pull repourl branchname

默认的branch_name是master,这会将远程的repo拉过来并且和当前分支合并。

远程工作时,可以添加别名

$git remote add aliasname repourl

$git fetch alias_name

fetch命令只会拉下来更新,而不会执行merge工作

$git merge aliasname/branchname

github 创建项目主页****page

  • 登录github 新建一个 mybook项目 仓库
  • 建立本地git的远程关联

git remote add mybook git@github.io/xxx.git //

git checkout -b ph-pages // 建立ph-pages分支

git add xxx

git commit -m "" //将要发布的内容提交入库

git push mybook -u ph-pages //推送到远程仓库并 -u参数建立绑定

通过访问****http:///github.io/<****项目名****> 访问项目主页

git log 查看提交日志

glgga git log --all --decorate --graph --decorate参数 显示所标记的标签

glola ||**glol **

ZSH git命令简写

gb='git branch'

gba='git branch -a'

gbda='git branch --merged | command grep -vE "^(*|\smaster\s$)" | command xargs -n 1 git branch -d'**

gbl='git blame -b -w'

gbnm='git branch --no-merged'

gbr='git branch --remote'

gbs='git bisect'

gbsb='git bisect bad'

gbsg='git bisect good'

gbsr='git bisect reset'

gbss='git bisect start'

g='git'

ga='git add'

gaa='git add --all'

gapa='git add --patch'

gc='git commit -v'

gc!='git commit -v --amend'

gca='git commit -v -a'

gca!='git commit -v -a --amend'

gcan!='git commit -v -a -s --no-edit --amend'

gcam='git commit -a -m'

gcb='git checkout -b'

gcf='git config --list'

gcl='git clone --recursive'

gclean='git clean -fd'

gpristine='git reset --hard && git clean -dfx'

gcm='git checkout master'

gcmsg='git commit -m'

gco='git checkout'

gcount='git shortlog -sn'

compdef gcount=git

gcp='git cherry-pick'

gcs='git commit -S'

gd='git diff'

gdca='git diff --cached'

gdct='git describe --tags git rev-list --tags --max-count=1'

**gdt='git diff-tree --no-commit-id --name-only -r' **

gdw='git diff --word-diff'

gf='git fetch'

gfa='git fetch --all --prune'

gfo='git fetch origin'

gg='git gui citool'

gga='git gui citool --amend'

ggpull='git pull origin $(git_current_branch)'

ggpush='git push origin $(git_current_branch)'

ggsup='git branch --set-upstream-to=origin/$(git_current_branch)'

ggpur='ggu'

gignore='git update-index --assume-unchanged'

gignored='git ls-files -v | grep "^[[:lower:]]"'

git-svn-dcommit-push='git svn dcommit && git push github master:svntrunk'

gk='\gitk --all --branches'

gke='\gitk --all $(git log -g --pretty=format:%h)'

gl='git pull'

git log --all --decorate --graph

glg='git log --stat'

glgp='git log --stat -p'

glgg='git log --graph'

glgga='git log --graph --decorate --all'

glgm='git log --graph --max-count=10'

glo='git log --oneline --decorate'

glol="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

glola="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --all"

glog='git log --oneline --decorate --graph'

glp="_git_log_prettily"

gm='git merge'

gmom='git merge origin/master'

gmt='git mergetool --no-prompt'

gmtvim='git mergetool --no-prompt --tool=vimdiff'

gmum='git merge upstream/master'

gp='git push'

gpd='git push --dry-run'

gpoat='git push origin --all && git push origin --tags'

gpu='git push upstream'

gpv='git push -v'

gr='git remote'

gra='git remote add'

grb='git rebase'

grba='git rebase --abort'

grbc='git rebase --continue'

grbi='git rebase -i'

grbm='git rebase master'

grbs='git rebase --skip'

grh='git reset HEAD'

grhh='git reset HEAD --hard'

grmv='git remote rename'

grrm='git remote remove'

grset='git remote set-url'

grt='cd $(git rev-parse --show-toplevel || echo ".")'

gru='git reset --'

grup='git remote update'

grv='git remote -v'

gsb='git status -sb'

gsd='git svn dcommit'

gsi='git submodule init'

gsps='git show --pretty=short --show-signature'

gsr='git svn rebase'

gss='git status -s'

gst='git status'

gsta='git stash'

gstaa='git stash apply'

gstd='git stash drop'

gstl='git stash list'

gstp='git stash pop'

gsts='git stash show --text'

gsu='git submodule update'

gts='git tag -s'

gtv='git tag | sort -V'

gunignore='git update-index --no-assume-unchanged'

gunwip='git log -n 1 | grep -q -c "--wip--" && git reset HEAD~1'

gup='git pull --rebase'

gupv='git pull --rebase -v'

glum='git pull upstream master'

gwch='git whatchanged -p --abbrev-commit --pretty=medium'

gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit -m "--wip--"'

分支合并

rebase,merge

分支变基:

$ git checkout dev

$ git rebase master

git checkout master

$ git merge dev

gitsvn命令对比

常用的svngit命令对比如下:

svnadmin create ------------------------------> git init

svn co ------------------------------> git clone

svn update ------------------------------> git pull

svn add ------------------------------> git add

svn commit ------------------------------> git add, git commit

svn status ------------------------------> git status

svn switch <branch> ------------------------> git checkout <branch>

svn merge <branch> ------------------------> git merge <branch>

svn revert <file> ------------------------------> git checkout <file>

前端