-
Notifications
You must be signed in to change notification settings - Fork 7
git常见问题及解决
目录
[TOC]
错误信息类似于:
# https://git-scm.com/book/zh/v2/自定义-Git-配置-Git
~ git diff > tmp.patch
warning: LF will be replaced by CRLF in src/app/theme/components/menuItem/menuItem.component.css.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in config/webpack.dev.js.
CRLF 是 carriage return line feed的缩写。中文意思是回车换行。
LF是line feed的缩写,中文意思是换行。
CRLF->Windows-style
LF->Unix Style
CR->Mac Style
CRLF表示句尾使用回车换行两个字符(即我们常在Windows编程时使用"\r\n"换行)
LF表示表示句尾,只使用换行.
CR表示只使用回车.
在Git通过下面的命令配置:
$git config --global core.autocrlf true
# Configure Git on Windows to properly handle line endings
设置为true,添加文件到git仓库时,git将其视为文本文件。他将把crlf变成lf。
设置为false时,line-endings将不做转换操作。文本文件保持原来的样子。
设置为input时,添加文件git仓库石,git把crlf编程lf。当有人Check代码时还是lf方式。因此在window操作系统下,不要使用这个设置。
- true: x -> LF -> CRLF
- input: x -> LF -> LF
- false: x -> x -> x
- 其他的命令
# AutoCRLF
#提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf true
#提交时转换为LF,检出时不转换
git config --global core.autocrlf input
#提交检出均不转换
git config --global core.autocrlf false
# SafeCRLF
#拒绝提交包含混合换行符的文件
git config --global core.safecrlf true
#允许提交包含混合换行符的文件
git config --global core.safecrlf false # 设置这个命令会把警告取消
#提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn
当添加一个仓库后,推送文件上去不允许,错误信息类似于:
git push github master
To https://github.com/user/my_wiki.wiki.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://github.com/user/my_wiki.wiki.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
如果远程仓库的代码没用了,不要了,则可以选择强推代码解决问题:
~ git push -u github master -f
使用git的时候出现类似下面的信息:
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
解决方法,终端下输入下面命令:
xcode-select --install
需要安装一会就可以了。
非正常关闭vi编辑器时会生成一个.swp文件。
使用vi,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,
vi就会生成这么一个.(filename)swp文件 以备不测(不测下面讨论),如果你正常退出,那么这个这个swp文件将会自动删除 。
swp文件的来历,当你强行关闭vi时,比如电源突然断掉或者你使用了Ctrl+ZZ,vi自动生成一个.swp文件,
下次你再编辑时,就会出现一些提示。
比如你正在使用vi
编辑file.txt
文件,然后强制关闭终端,这个时候就会产生.file.txt.swp
文件。
当再次使用vi
打开file.txt
文件就会出现提示, 这个时候可使用下面的命令来恢复未保存的操作:
vi -r file.txt
这个时候保存中断之前的操作后,.swp
文件不会自动删除,需要自己手动删除:
rm .file.txt.swp
在使用git命令的时候,如果文件名是中文的,就会出现如\200\273\347\273\223.png
的乱码。
解决方法,在终端中输入如下命令:
git config --global core.quotepath false
core.quotepath设为false的话,就不会对0x80以上的字符进行quote。中文显示正常。
参考链接: http://blog.csdn.net/tyro_java/article/details/53439537
在mac电脑下,git仓库中有文件夹首字母大写,修改成首字母小写后,git没有识别出文件夹的修改, 可使用如下命令设置为大小写敏感:
git config core.ignorecase false
由于修改了文件名,仅仅是文件名首字母大小写修改了,然后就导致git同时把这一个文件跟踪了两次,比如我修改了文件夹名字,由Settings 改成 settings,导致文件夹下的文件重复出现:
modified: src/views/Settings/TagSet/TagDialog.jsx
modified: src/views/settings/TagSet/TagDialog.jsx
此时可使用git rm --cached
来取消对重命名之前的文件跟踪
git rm --cached src/views/Settings/TagSet/TagDialog.jsx
rm 'src/views/Settings/TagSet/TagDialog.jsx'
取消跟踪后,使用git status
查看,就会发现这个文件自动添加到删除中了:
~ git rm --cached src/views/Settings/TagSet/TaDialog.jsx
rm 'src/views/Settings/TagSet/TagDialog.jsx'
~ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: src/views/Settings/RuleSet/RuleDialog.jsx
deleted: src/views/Settings/TagSet/TagDialog.jsx
modified: src/views/settings/RuleSet/RuleDialog.jsx
modified: src/views/settings/TagSet/TagDialog.jsx
产生原因:服务器提交了错误或者无用的代码,本地回滚代码,然后把代码强推到服务器上,由于gitlab上有分支保护导致代码推送失败:
git push origin master -f
Total 0 (delta 0), reused 0 (delta 0)
remote: GitLab: You are not allowed to force push code to a protected branch on this project.
To http://git.baijiahulian.com/yunying/bi-fe.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'http://git.baijiahulian.com/yunying/bi-fe.git'
-
在gitlab上查看保护的分支
在gitlab上打开项目,点击
Repository
, 然后点击Branches
,就能看见所有分支,在分支名字后面有个绿色的protected
就是保护分支。 -
关闭gitlab上的保护分支(需要项目的master或者Owner)
点击项目右上角(用户logo下面)的小齿轮,选择
Protected Branches
,在打开的页面里面就能看见保护的分支了,然后点击保护分支右边的Unprotect
,就能删除对这个分支的保护了。 -
开启gitlab上的保护分支(需要项目的master或者Owner)
点击项目右上角(用户logo下面)的小齿轮,选择
Protected Branches
, 在Protect a branch
中输入分支名字,选择对应权限,然后点击Protect
,就会立刻添加一个保护分支了。
改完代码匆忙提交,上线发现有问题,怎么办? 赶紧回滚.
改完代码测试也没有问题,但是上线发现你的修改影响了之前运行正常的代码报错,必须回滚.
回滚分两种情况
当代码还在本地仓库,在add、commit后发现代码有问题,想回退到以前的提交点,此时可用reset命令:
git reset option 历史提交点
-
option:reset的操作选项可用命令有:
--hard
: 移动HEAD,更新index,更新工作目录(working Directory)--mixed
: 移动HEAD,更新index, 此选项是reset的默认选项,也就是不写option默认就是此操作。--soft
: 只移动HEAD, -
历史提交点: commit标识代码, 也就是
git log
命令中的一串字符串,如:d42a68c81, 通常前8位以上就可以
reset
命令会以特定的顺序重写这三棵树,在你指定以下选项时停止:
- 移动 HEAD 分支的指向 (若指定了 --soft,则到此停止)
- 使索引看起来像 HEAD (若未指定 --hard,则到此停止)
- 使工作目录看起来像索引
使用例子:
git reset --hard 9e53f30b7ab56e
HEAD is now at 9e53f30 开始页面:添加提交按钮。
此时所有历史commit记录可使用git reflog
来查找:
git reflog
26c5d5a (HEAD -> test, origin/test) HEAD@{0}: reset: moving to 26c5d5a
9e53f30 HEAD@{1}: reset: moving to 9e53f30b7ab56e
26c5d5a (HEAD -> test, origin/test) HEAD@{2}: commit: 添加测试包
9e53f30 HEAD@{3}: commit: 提交信息
如果回退错了,可使用上面命令把最早的提交在回退回来。
代码刚push,还没有被其他开发人员拉取,或者还没有用于自动部署工具拉取(如Jenkins)。
此时使用git reset
回退后,然后使用git push -f
来强推代码到仓库即可:
git reset --hard 9e53f30b7
HEAD is now at 9e53f30 开始页面:添加提交按钮。
git push -f
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create merge request for tt:
remote: http://git.github.com/finance-system/zi-fe/merge_requests/new?merge_request%5Bsource_branch%5D=tt
remote:
To http://git.github.com/finance-system/zi-fe.git
+ 26c5d5a...54ebaf8 tt -> tt (forced update)
注意,如果推送的分支是保护分支(gitlab仓库有保护分支设置),那么只能是master权限才能强推代码,或暂时把保护分支关闭才能正确推送代码。
由于此时代码已扩散了,如果在使用reset回退然后强推则会导致被人在拉取你代码的时候导致冲突,拉取失败。
此时可使用git revert
来回退了:
git revert用于反转提交,执行evert命令时要求工作树必须是干净的.
git revert用一个新提交来消除一个历史提交所做的任何修改.
revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代码更新.(这里不会像reset造成冲突的问题)
revert 使用,需要先找到你想回滚版本唯一的commit标识代码:
git revert 26c5d5a7ce5b
[tttt 5774123] Revert "哈勃包名更改测试。"
3 files changed, 3 insertions(+), 5 deletions(-)
git revert 26c5d5a7ce5b
命令会回把26c5d5a7ce5b
的提交回退,并生成一次提交记录。
如果想一次revert多个提交点:
git revert 2c71073d2..b688116bde
注意:
2c71073d2 :是旧提交点,也就是比 b688116bde提交时间早
提交点是两个点之间的,每一个提交都会生成已给提交记录。
使用2c71073d2..b688116bde
其实比单独一个2c71073d2
是一样的,如果回退5个提交,则会出现5次提交记录。
如果别人已经拉取你的分支代码了,还可以然他删除这个分支,然后从新拉取代码。
-
本地使用
git reset
回退到一个历史版本中。 -
使用
git push -f
强推到服务器仓库。 -
别人要做如下操作:
git checkout master // 切换到其他分支 git branch -d tt // 删除有问题的分支 git fetch -a // 提取所有git信息到本地 git checkout tt // 此时你的新分支代码就没问题了 git pull
-
如果是Jenkins构建的,可在Jenkins配置里面的脚本先执行下面代码:
git checkout master && git branch -d $branch && git fetch -a && git checkout $branch && git pull"
$branch
是Jenkins里面的分支名字变量。
此方法统计从提交的开始时间到结束这一段时间所有的提交代码
git log --since=2018-01-01 --until=2018-12-31 --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 }'
added lines: 36874, removed lines: 12214, total lines: 24660
上面的git命令按照2018-01-01
到2018-12-31
这段时间来统计你的代码提交量
此方法可以统计项目中,该用户的工作量
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 }'
added lines: 29146, removed lines: 7457, total lines: 21689
注意把username
改成真正的用户名。
此方法过滤一段时间内,某个用户的代码量
git log --author="username" --since=2018-10-01 --until=2018-12-31 --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 }'
added lines: 2068, removed lines: 953, total lines: 1115
注意把username
改成真正的用户名。
查看仓库提交者排名前 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 log --stat|perl -ne 'END { print $c } $c += $1 if /(\d+) insertions/'