苏苏的博客

简约至极

git基本使用

git配置

git config --global user.email "1126045770@qq.com"
git config --global user.name "sucongohu"

git config --global core.autocrlf false
git config --global color.ui true
git config --global credential.helper store

git config --global alias.lg "log --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci,%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
git config --global alias.laststash "diff stash@{0}^!"

以上分别是设置用户信息,禁止转换换行符,颜色高亮,记住密码,设置别名列出分支图. 设置别名后,可以使用 git lg 查看各个分支关系

设置core.autocrlf false 提交检出均不转换 , 否则同时在Mac,Windows,Linux 跨平台协作开发,eslint 检测换行符错误会很头疼.

默认的core.pager 是less

git config --global core.pager "less -FRSX"

可以修改为diff-so-fancy

git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"

http://www.cnblogs.com/sdgf/p/6237847.html

记住密码

if [ ! -f ~/.git-credentials ]; then touch ~/.git-credentials; fi

cat ~/.git-credentials

如果不行,可以手动使用http://user:pass@git.xx.cn 格式写入此文件.

还可以记在内存中,指定有效期 git config --global credential.helper "cache --timeout=3600"

git config credential.helper store 不添加--global 存储在当前项目中

git-for-windows

配置不使用window系统的系统凭据

git config --global --unset credential.helper
git config --system --unset credential.helper

使用系统凭据记住密码

git config --global credential.helper manager

如果修改了git的账户密码,需要清除osxkeychain记住的密码,可以 git config --global credential.helper osxkeychain

要清楚系统凭据,还需要使用window的凭证管理器,管理这些记住的用户身份

使用git还经常碰到文件权限发生变化,也显示文件变动了,需要提交,如果你不想将文件权限的变动纳入版本控制可以

git config core.filemode false

对于一些本地和服务器不一致的配置文件,git status每次查看都显示出来,git add -u又会一不小心提交,可以使用 忽略已追踪文件的变动

git update-index --assume-unchanged PATH_TO_FILE

将一些文件移除版本控制

git rm -r --cached <folder>

git rm --cached <file>

then commit, push

https://stackoverflow.com/questions/1274057/how-to-make-git-forget-about-a-file-that-was-tracked-but-is-now-in-gitignore

批量操作当前目录下的所有仓库

for i in * ;do cd $i && pwd && git gc; cd -;done;

参数 说明


%H	commit hash
%h	commit short hash
%T	tree hash
%t	tree short hash
%P	parent hash
%p	parent short hash
%an	作者名字
%aN	.mailmap 中对应的作者名字
%ae	作者邮箱
%aE	.mailmap 中对应的作者邮箱
%ad	–date=制定的日期格式
%aD	RFC2822 日期格式
%ar	日期格式,例如:1 day ago
%at	UNIX timestamp 日期格式
%ai	ISO 8601 日期格式
%cn	提交者名字
%cN	.mailmap 对应的提交的名字
%ce	提交者邮箱
%cE	.mailmap 对应的提交者的邮箱
%cd	–data=制定的提交日期的格式
%cD	RFC2822 提交日期的格式
%cr	提交日期的格式,例如:1day ago
%ct	UNIX timestamp 提交日期的格式
%ci	ISO 8601 提交日期的格式
%d	ref 名称
%e	encoding
%s	commit 信息标题
%f	过滤 commit 信息的标题使之可以作为文件名
%b	commit 信息内容
%N	commit notes
%gD	reflog selector, e.g., refs/stash@{1}
%gd	shortened reflog selector, e.g., stash@{1}
%gs	reflog subject
%Cred	切换至红色
%Cgreen	切换至绿色
%Cblue	切换至蓝色
%Creset	重设颜色
%C(color)	制定颜色,as described in color.branch.* config option
%m	left right or boundary mark
%n	换行
%%	a raw %
%x00	print a byte from a hex code
%w([[,[,]]])	switch line wrapping, like the -w option of git-shortlog(1).

一个命令推送到多个服务端vim .git/config ,添加一个区段,例如:

[remote "all"]
        url = https://git.oschina.net/suconghou/mvc.git
        url = https://suconghou@git.coding.net/suconghou/mvc.git
        url = https://github.com/suconghou/mvc.git

以后可以使用git push all master一次推送到多个后端

使用远程的某一分支,覆盖本地代码

git fetch --all && git reset --hard origin/master && git pull

远程分支可能有删除的,同步到本地

git fetch -p origin

git 相关统计

查看git上个人代码量

git log --author="username" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

统计每个人的增删行数

git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

查看仓库提交者排名前 5

git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5

贡献者统计:

git log --pretty='%aN' | sort -u | wc -l

提交次数统计:

git log --oneline | wc -l

git clone

git clone https://xxx --branch $BRANCH --single-branch --depth=1

clone 某个分支的最新代码,不要历史记录

git clone -b branch url 使用-b参数,可以clone 指定的分支.

git使用代理

使用代理

git config --global http.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:1080

取消使用代理

git config --global --unset http.proxy
git config --global --unset https.proxy

执行git的时候动态指定

git clone -c https.proxy=socks5://127.0.0.1:1080  https://github.com/me/test.git

使用本地shadowsocks代理

git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'

https://segmentfault.com/a/1190000007834504

git回退

当前工作目录的修改都放弃 git checkout .

如果不小心添加了不必要的文件,但是还没有commit,想要撤销添加 git reset FILE_TO_PATH

如果最近的几次的提交完全是错误的,想要放弃,回滚到之前的某一个点继续开发

git reset --hard 要恢复的点HASH 然后 git push -f 强制提交,原先的错误提交将被强制清除,同时团队其他开发人员,也需要重新clone

更好的是 在要恢复的点新建分支,继续开发.

git reset 与 git revert

https://www.cnblogs.com/chenweichu/articles/5834209.html

git分支管理

1.创建分支

git branch <分支名>

2.切换到分支

git checkout <分支名>

3.创建一个分支并切换过去

git checkout -b <分支名>

或者

git checkout -b <分支名> master

后面是跟一个master说明创建的develop分支是基于当前的master, 如果当前就在master分支,则可以不写。 如果当前分支HEAD指向的是别的分支,又想基于master分支创建,就必须写master

git new branch from scratch

新建一个孤立的分支 git checkout --orphan <branchname>

清除不必要的数据 git rm --cached -r . && git rm -rf .

总结为

git checkout --orphan newbranch
git rm -rf .
<do work>
git add your files
git commit -m 'Initial commit'

如果版本小于1.7.2 不支持--orphan 可以

git symbolic-ref HEAD refs/heads/newbranch
rm .git/index
git clean -fdx
<do work>
git add your files
git commit -m 'Initial commit'

在没有任何提交之前git branch不会检查到这个分支

更简便的方法新建一个空白的分支

true | git mktree | xargs git commit-tree | xargs git branch branchname

然后直接切换到这个分支,git checkout branchname

新建立的分支无任何文件和提交历史,超级赞!

执行git push --set-upstream origin branchname将新建的分支提交到远程并设置本地分支与远程分支的关联

参考

http://stackoverflow.com/questions/13969050/how-to-create-a-new-empty-branch-for-a-new-project

http://stackoverflow.com/questions/1384325/in-git-is-there-a-simple-way-of-introducing-an-unrelated-branch-to-a-repository

4.分支合并

如:要将develop分支合并和master分支 首先切换的master分支:git checkout master 然后执行合并操作:git merge develop 如果有冲突,会提示你,调用git status查看冲突文件。 解决冲突,然后调用git addgit rm将解决后的文件暂存。 所有冲突解决后,git commit提交更改。

git merge brancha branchb 合并其他分支 到当前所在的分支,当然也可以合并master分支的修改到当前分支

5.删除分支

删除本地分支,删除分支之前记得先合并,以免数据丢失

git branch -d <分支名>

git push [远程名] [本地分支]:[远程分支] 本地分支的数据推送到远程分支,如果远程分支不存在,将会自动创建

如果本地分支为空格,则将删除远程分支 git push origin :deletebranch

等同于 git push origin --delete deletebranch

6.显示所有分支

git branch -a

显示远端分支

git branch -r

git push --all 把所有本地分支都推到远端

git pull origin remotebranch:localbranch 将远程某分支拉倒本地某分支,当本地分支和远程分支名称相同时,只写一个就可以

提交本地指定的分支 到 远程的一个分支

git push origin localbranch:remotebranch (注意,如果本地分支不写,就是删除远程分支的命令)

将所有commit压缩为一个

https://stackoverflow.com/questions/1657017/how-to-squash-all-git-commits-into-one/9254257#9254257

:%s/pick/squash/g in VIM to replace all

操作完以后需要git push -f

git tag 管理

1.git tag

在控制台打印出当前仓库的所有标签

2.git tag -l ‘v0.1.*’

搜索符合模式的标签

3.git tag v0.1.2-light

创建轻量标签

4.git tag -a v0.1.2 -m “0.1.2版本”

创建附注标签

git标签分为两种类型:轻量标签和附注标签。轻量标签是指向提交对象的引用,附注标签则是仓库中的一个独立对象。建议使用附注标签。

5.git tag -d v0.1.2

删除标签

6.git push origin v0.1.2

将v0.1.2标签提交到git服务器 git push origin –-tags 将本地所有标签一次性提交到git服务器 通常的git push不会将标签对象提交到git服务器,所以我们需要进行显式的操作:

git worktree

git worktree add -b <新分支名> <新路径> <从此分支创建>

这样,新路径里会出现一份copy,这个仓库里只有一个 .git 文件用来记录这是主仓库的一个工作目录。

自此,这两个工作目录在工作上看起来就像两个独立的仓库一样,都可以运行各种命令,包括切换分支。

相比于克隆多个仓库,使用这种方法创建的多个目录,有诸多好处:

只有一个仓库会占用版本库的空间,其它只占用工作目录的空间,对大型项目而言非常节省空间。 因为所有工作目录共享一个仓库,所以一个更新意味着整个更新(A 目录里对分支做的改动,B 目录里切到此分支也是改动后的;避免到时候找不到某个未推送的改动改到了哪个仓库)

git stash 操作

1.git stash 可用来暂存当前正在进行的工作, 比如想pull 最新代码, 又不想加新commit, 或者另外一种情况,为了fix 一个紧急的bug, 先stash, 使返回到自己上一个commit, 改完bug之后再stash pop, 继续原来的工作。

git stash
//do some work
git stash pop

2.同样可以使用 git stash save “work in progress for foo feature” 添加标记

3.当你多次使用git stash命令后,你的栈里将充满了未提交的代码,这时候你会对将哪个版本应用回来有些困惑, git stash list 命令可以将当前的Git栈信息打印出来,你只需要将找到对应的版本号,例如使用git stash apply stash@{1}就可以将你指定版本号为stash@{1}的工作取出来,当你将所有的栈都应用回来的时候,可以使用git stash clear来将栈清空。

查看stash与当前的差异

git stash show -p 最新的差异

git stash show -p stash@{1} 指定 stash

git diff stash@{0} master 与与任意版本对比

git diff --name-only stash@{0} master 仅仅查看哪些文件变化

查看文件变迁记录

查看某版本的指定文件

git show <commitHash>:path/to/file

查看4次提交前的某个文件

git show HEAD~4:src/main.c

可以使用管道符导出这个文件

注意 git show 3.0 src/components/uploadContainer.vue

git show 3.0:src/components/uploadContainer.vue

是不一样的操作,前者是显示的diff, 后者是指定节点的文件数据

查看某一文件的的所有版本的对比变化

# include patch displays in the commit history
git log -p
git whatchanged -p
# only get history of those commits that touch specified paths
git log path/a path/b
git whatchanged path/c path/d

git log app/api/article.php 查看一个文件的所有版本号,要查看版本间内容对比使用 git log -p app/api/article.php

git diff

git diff 默认是工作目录(Working tree)和暂存区域快照(index)之间的差异

查看已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异

git diff --cached

git diff --staged

显示工作版本(Working tree)和HEAD的差别 git diff HEAD

直接将两个分支上最新的提交做diff git diff topic mastergit diff topic..master

比较上次提交commit和上上次提交 git diff HEAD^ HEAD

比较两个历史版本之间的差异 git diff SHA1 SHA2

git diff HEAD application/config/config.php

diff 还有两种简要形式

git diff HEAD --stat src

git diff HEAD --name-status src

给Git仓库瘦身

使用git gc --aggressive 来整理仓库,压缩合并碎片文件能减小仓库大小.

使用git prune 删除一些不会被使用的残留数据,使用git prune -n可以查看将要被删除的数据.

如果想要更加暴力的操作git减小仓库大小,一般使用git-filter-branch,不过操作比较麻烦,可以参考官方的操作 http://git-scm.com/book/zh/v1/Git-内部原理-维护及数据恢复

这里提供一个工具https://rtyley.github.io/bfg-repo-cleaner/

使用这个操作更加方便

下载bfgjar文件,使用java -jar bfg.jar运行,也可以自己写一个alias

首先git clone --mirror 地址

bfg --strip-blobs-bigger-than 10M .

bfg --strip-blobs-bigger-than 1M --delete-files '{*.jar,*.zip,*.gz,*.war,*.jpg,*.png,*.jpeg}'

最后执行git reflog expire --expire=now --all && git gc --prune=now --aggressive

使用du -sh查看最终文件夹大小.

手动清除大文件

git count-objects -v 可以查看git的磁盘使用量

仓库中存在一个idx文件是索引文件 .git/objects/pack/pack-*.idx

从此文件中可查询一些大对象

git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10

使用git rev-list --objects --all可以列出所有 commit SHA 值,blob SHA 值及相应的文件路径

我们两者进行对比就找出了哪些大文件的名字及其SHA,使用下面的命令我们可以一下子得出有哪些大文件.

git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"

git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch your-file-name' --tag-name-filter cat -- --all

your-file-name 可以写多个空格隔开。执行完以后,可以再次执行上面的git rev-list再次查看还有那些大文件。

git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')" | awk '{print$2}' | xargs
rm -rf .git/refs/original .git/logs/
git gc
git prune
git count-objects -v

修改完要进行一次force push git push -f , 其他人需要重新clone

git 查找

git grep搜索仓库下的代码,比grep更加快

使用:https://git-scm.com/docs/git-grep

如只在markdown文件中搜索 git grep "make" '*.MD'

git打包

时常我们会使用github或者其他git托管网站的下载zip包功能,下载的压缩包仅包含仓库里的现有文件,不含.git文件夹

那么我们本地的仓库如何做到呢,需要自己使用zip命令自己压缩排除文件吗.

其实git已经自带这个功能了,可以将任意版本的数据导出为压缩包.

将 master以zip格式打包到指定文件git archive --format zip --output /path/to/file.zip master

git archive v0.1 | gzip > site.tgz
git archive master > ./fds.zip

最快捷的直接使用git archive master -o a.tgz

使用 -o a.tgz 或者 a.tar.gz 生成gzip格式的, -o a.zip 生成zip格式的.

git-usage

从源码静态编译git

apk update && apk upgrade
apk add curl gcc g++ make zlib-dev perl
curl https://www.kernel.org/pub/software/scm/git/git-2.10.2.tar.xz | tar xJ
cd git-2.10.2
./configure --prefix=/usr/local --with-curl   CFLAGS="${CFLAGS} -Os -static `pkg-config --static --libs libcurl`"  NO_TCLTK=1 NO_PERL=1 NO_GETTEXT=1
make -j4
make install

svn

svn revert xx.html git checkout xx.html 类似,还原文件的更改

账号文件:/etc/svn-auth-users 密码重置:htpasswd /etc/svn-auth-users conghou.su 新添加用户:同上 删除用户:打开账号文件删除用户所在行即可

修改文件以后需要 service httpd restartsystemctl restart httpd 或者 apachectl 控制

htpasswd 如果没有

sudo apt-get install apache2-utils

对于 centos , 使用如下命令查看在哪个包中有。

yum provides \*bin/htpasswd

yum whatprovides */htpasswd

一般是httpd-tools, yum install httpd-tools 即可