**git** 使用笔记

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

git与svn命令对比

常用的svn与git命令对比如下:

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>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本文作者陈云峰,转载请注明。 这篇文章记录个人常用的一些命令,和记不住的一些命令,转载了并不断更新。 Git官网 ...
    陳云峰阅读 2,988评论 0赞 24
  • git常用命令 GIT常用命令备忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章阅读 8,953评论 1赞 26
  • 原文地址主要用到的命令: git config user.name 设置用户名 git config user....
    AFinalStone阅读 635评论 0赞 2
  • 前几天加了一个微信朋友,让我颇为好奇的是他的微信头像居然用了他妻子的单人照片。 这是我见过的唯一用自...
    桔桔_a044阅读 954评论 0赞 2
  • 一个细小的病证会立刻将你打回原型。孤独的、弱小的、思乡的情感顷刻涌来,最后,用镇定的自己给命运一个回击。
    作死不睡者阅读 267评论 0赞 0

友情链接更多精彩内容