跳转至

面试

面试官:

由于工程架构的变动,现在A仓库被废弃了,创建了一个与A 仓库内容完全一样的仓库B,但是有一个同事还不知道这件事,不小心往A仓库提交了好多代码,问现在如何

将他提交到废弃仓库A的commit

转移到新仓库B?

首先思考:

最容易想到的一定是“笨办法

把所有改动的实件复制粘贴过去

但这是初级程序员的做法!如果改动的文件超级多,那复制粘贴要搞到猴年马月去!

这种操作一定是需要通过 Git 操

作来完成的,才足够规范和便捷。

接着思考:

哪种 Git 操作可以完成将内容从

一个地方同步到另一个呢?

我们常常通过 merge 操作将一个分支的改动同步到另一个分支。很多程序员会选择用 rebase

操作代替 merge 操作,也能达到

类似的效果。

这个回答及格了吗:

根据以上思考过程,我们可以回答可以使用 merge 操作或者 rebase操作,将A仓库的commit 同步到

B 仓库。

问题在于:

① rebase 操作真的可以跨仓库执行吗?

操作的细节呢?有没有更完美的方案?

这个回答我最多给60分!

满分回答在这里:

我们的需求是在两个原本内容相同的仓库之间同步一些增量的改动,那么首先一定要把两个仓库关联起来,才能实现,这是大前提!如何关联?在B仓库使用:

git remote add arepo https://xxx/A

即可将A 仓库添加为B仓库的一个远程代码源!并命名为了 arepo

C

添加了远程源之后我们需要将A仓库代码拉取下来:

git fetch repo

此时在A仓库找到需要同步到B仓

库的 commit hash ,假如该哈希为

hashxxx,那么只需要执行:

git cherry-pick hashxxx

*每个 git commit 都会对应一个唯一的哈希值喔~可以通过此确定到某一次具体的提交!

此时如果没有任何冲突,那么就会

直接把目标 commit 同步过来啦!

如果有冲突,那就和 merge 操作

一样解决冲突就好啦!

最后一定要把之前添加的 A仓库的

远程源给移除,把B仓库恢复成最

开始的样子:

git remote remove arepo

为什么不用merge:

看起来添加 A 仓库为远程源之后用 merge操作貌似也能达到一样的目的诶!那么为什么满分回答一定是 cherry-pick 呢?

这是因为:它们的粒度不同!

① merge 操作是分支粒度的,只能将整个分支 merge 到另一个分支上;

② pick 操作是 commit 粒度的,我可以精确控制我要把哪些commit 搬过来,不想要的我可以不搬!

*作为面试官,如果看到这么深入的理解,我只能大呼:100分!100分!

业务流程

1.在分支开发

2.将master同步给开发分支

3.合并冲突并解决

4.推送pr

日常工作中,我们可能在 Git 使用上频繁交互的流程大致会是这样的(不同规范下会有一些区别,但是大差不大):

  1. 来了一个新需求,我们会从 master checkout 一个新的 feature 分支出来进行开发。
  2. 开发完某个功能点,我们会执行 git add 将代码提交到暂存区。
  3. 执行 git commit 将代码提交到本地仓库
  4. 执行 git push 将代码提交到远端分支
  5. 当我们开发完所有需求之后,可能会设立一个专门的测试分支比如名叫 dev 的分支,那么我们就把代码合并到这个测试分支上,发布测试环境进行测试。
  6. 测试完毕之后,我们就需要合代码了,这个时候,我们可以发起一个 merge request,将我们的代码走 CR 流程合并到 master 分支。
  7. 在提交 MR 的过程中,我们一般需要先自己预先将 master 分支的代码合并到当前需要被合并的分支,提交并解决冲突。

git常见错误大全

github上传大文件

github客户端最高支持100Mb文件上传,如果要>100M只能用git-lfs,但是测试发现即使用git lfs,我上传2.5GB也不行,测试737M文件可以,GitHub 目前 Git LFS的总存储量为1G左右,超过需要付费。(上传失败时,可以开启VPN进行上传)。过程

自己在github新建一个仓库,然后git clone到本地

切换到项目目录

git lfs track xxx.zip
git add .
git commit -m "xxx(关于这次推送的相关信息)"
git push

lfs的常用命令

git lfs track '*.pbix'  #告知LFS管理文件类型
git lfs track 查看LFS管理的所有类型文件
git add .  #将工程文件全部添加进commit提交列表中
git commit -m 'Add new large assets' #附加提交日志
git lfs ls-files #查看LFS管理了哪些文件
git push #全仓库推送
cd upload #进入名为upload的文件夹,提前将要上传的大文件放入该文件夹下
git init #创建本地仓库环境
git lfs install #安装大文件上传应用
git lfs track * #追踪要上传的大文件,*表示路径下的所有文件
git add .gitattributes #添加先上传的属性文件(要先上传属性文件,不然有可能失败)
git commit -m "pre" #添加属性文件上传的说明
git remote add origin https://github.com/xxxx.git #建立本地和Github仓库的链接,.git链接在网页端clone的HTTPS中获取
git push origin master #上传属性文件
git add * #添加要上传的大文件,*表示路径下的所有文件
git commit -m "Git LFS commit" #添加大文件上传的说明
git push origin master #上传大文件
git pull --rebase origin master
git push -u origin master

Authentication failed for

原因: 此错误造成原因是登录git账号时用户名或者密码错误使验证失败导致命令执行不成功,抛出此错误

解决:

  1. 找到控制面板——用户账户——凭证管理器,到凭证中去重新修改git地址凭证保存的密码。
  2. 打开cmd面板,输入:git config --system --unset credential.helper,然后重新执行命令,在弹出的用户名及密码框中输入正确的账户密码即可验证通过

! [rejected] master -> master (fetch first)error: failed to push some refs to 'git@gitee.com:xxxxxxx'

原因: 出现这个问题是因为github中的README.md文件不在本地代码目录中

解决: 可以通过如下命令进行代码合并

git pull --rebase origin master`再`git push origin master

! [remote rejected] master -> master (pre-receive hook declined)

原因: git push不上去的原因在于所push的分支权限为protected,只有项目的管理员或者项目的管理员指派的具有相应权限的人才能进行push

解决:

  1. 进入所在项目的settings,点击进入Protected branches,点击unprotected将master分支的权限改变,即关闭master的protected权限
  2. 新建其它分支,将项目push到新建的分支上,后期再进行merge

Your local changes to the following files would be overwritten by merge

error: Your local changes to the following files would be overwritten by merge:
        protected/config/main.php
Please, commit your changes or stash them before you can merge.

原因:

团队其他成员修改了某文件并已提交入库,你在pull之前修改了本地该文件,等你修改完代码再pull时,这时会报错如下错误.

#1. 如果希望保留生产服务器上所做的改动,仅仅并入新配置项, 处理方法如下:
git stash  #备份当前工作区内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前工作区内容保存到Git栈中
git pull   #拉取服务器上当前分支代码
git stash pop   #从Git栈中读取最近一次保存的内容,恢复工作区相关内容。同时,用户可能进行多次stash操作,需要保证后stash的最先被取到,所以用栈(先进后出)来管理;
#pop取栈顶的内容并恢复,然后可以使用git diff -w +文件名 来确认代码自动合并的情况.
git stash list:#显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear:#清空Git栈

#2. 反过来,如果希望用代码库中的文件完全覆盖本地工作版本. 方法如下:
git reset --hard
git pull
#其中git reset是针对版本,如果想针对文件回退本地修改,使用
git checkout HEAD file/to/restore
#此方法即版本回退,不建议使用第二种。除非你再三确定不需要本地的修改了。

Pull is not possible because you have unmerged files

Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>'
as appropriate to mark resolution, or use 'git commit -a'.

原因:

文件冲突(本地的push和merge会形成MERGE-HEAD(FETCH-HEAD), HEAD(PUSH-HEAD)这样的引用。HEAD代表本地最近成功push后形成的引用。MERGE-HEAD表示成功pull后形成的引用。可以通过MERGE-HEAD或者HEAD来实现类型与svn revet的效果。将本地的冲突文件冲掉,不仅需要reset到MERGE-HEAD或者HEAD,还需要–hard。没有后面的hard,不会冲掉本地工作区。只会冲掉stage区

#解决方法
#查看冲突文件
git status #1也可以告诉我们冲突的文件 
Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:      file
#2手动解决冲突然后提交更改
vi file
git add file
git commit -m '解决冲突'

#另一种解决方法  错误示范
git reset --hard FETCH_HEAD
git pull
#上面的解决方法非常非常的霸道是可以解决这个错误但是它会回到初始的节点假如我有修改本地代码但是没有提交那么使用reset初始可能会丢失这些修改的代码
//注释:提交本地代码到工作区
//注释:如果有冲突,先解决冲突合并代码,然后提交
//注释:如果代码上没有冲突,但是提交的时候git提醒有冲突,那么先关闭编辑器,然后编译代码找到冲突,最后手动合并代码解决冲突
git add .
git commit -m '提交本地代码并且获取最新代码'
//注释:获取源dev分支最新代码
git pull origin dev
//注释:如有冲突就解决冲突 本地修改的代码要么提交要么隐藏后再获取,最好不要直接用reset

CONFLICT (content):Merge conflict in readme.txt

$ git merge feature1
Auto-merging readme.txt
CONFLICT (content):Merge conflict in readme.txt
Automatic merge failed; fix conflicts andthen commit the result.

原因:

不同分支代码合并时文件冲突造成的错误

1git status也可以告诉我们冲突的文件
#       both modified:      readme.txt  #冲突文件为readme.txt
2查看readme.txt的内容
<<<<<<<HEADmaster
=======fenzhi
>>>>>>> feature1
Git用<<<<<<<=======>>>>>>>标记出不同分支的内容我们修改如下后保存
master and fenzhi
3再提交
$ git add readme.txt 
$ git commit -m "hebing"
#git branch -d #会在删除前检查merge状态其与上游分支或者与head)。
#git branch -D #是git branch --delete --force的简写它会直接删除

The branch 'feature-vulcan' is not fully merged.

error:The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.

原因:删除本地未合并分支时抛出异常

#git 在删除分支的时候可以使用git branch -d featurename 也可以是git branch -D featurename 其中是有区别的
git branch -d #的时候如果本地分支没有被合并就会提示这个问题
git branch -D #是强制删除所以直接执行 强制删除就好了

Please move or remove them before you can merge. Aborting

原因:本地修改时与远端提交的代码冲突而又没有merge合并

#解决方法
git clean  -d  -fx ""
其中 
x  -----删除忽略文件已经对git来说不识别的文件
d  -----删除未被添加到git的路径中的文件
f  -----强制运行
#注意这样操作之后会删除本地的修改也就是选择与远端同步就是你写的修改的代码统统会被移除所以执行之前把自己冲突的代码先备份一下解决冲突后再还原然后再继续pull代码切记!!!!

fatal: remote origin already exists.

原因:

本地库已经关联了远程仓库地址,且跟当前输入地址冲突时抛出此异常

$ git remote rm origin   #(删除关联的origin的远程库)
$ git remote add origin git@github.com:(github名)/(git项目名).git    #就不会报错了
#如果输入$ git remote rm origin 还是报错的话error: Could not remove config section 'remote.origin'. 
我们需要修改gitconfig文件的内容找到你的git的安装路径找到一个名为gitconfig的文件打开它把里面的[remote "origin"]那一行删掉就好了

fatal: Couldn't find remote ref master或者fatal: 'origin' does not appear to be a git repository以及fatal: Could not read from remote repository.

原因:

未找到远程仓库,或者指定名称不是个存储库

git remote add origin git@github.com:djqiang/gitdemo.git
# origin 设置远程仓库别名
# git.... 远程仓库网址

warning: LF will be replaced by CRLF in qh.sh.The file will have its original line endings in your working directory

原因:

首先问题出在不同操作系统所使用的换行符是不一样的,主流操作系统的换行符有以下三种: ① Uinx/Linux采用换行符LF表示下一行(LF:LineFeed,中文意思是换行); ② Dos和Windows采用回车+换行CRLF表示下一行(CRLF:CarriageReturn LineFeed,中文意思是回车换行) ③ Mac OS采用回车CR表示下一行(CR:CarriageReturn,中文意思是回车)。

解决:(一般不用理会)

查看当前使用哪种换行符

git config core.autocrlf
# 此命令会有三个输出,“true”,“false或者input
# 为true时Git会将你add的所有文件视为文本文件将结尾的CRLF转换为LF而checkout时会再将文件的LF格式转为CRLF格式
# 为false时line endings不做任何改变文本文件保持其原来的样子
# 为input时add时Git会把CRLF转换为LF而check时仍旧为LF所以Windows操作系统不建议设置此值
git config --global core.autocrlf true   
#true的位置放你想使autocrlf成为的结果truefalse或者input
# 将core.autocrlf设为false即可解决这个问题如果你和你的伙伴只工作于Windows平台或者Linux平台那么没问题不过如果是存在跨平台的现象的话还是需要考虑一下
# 但当 core autocrlf为true时还有一个需要慎重的地方当你上传一个二进制文件Git可能会将二进制文件误以为是文本文件从而也会修改你的二进制文件从而产生隐患

fatal: Not a valid object name: 'master'.

在本地初始化新建的空git项目后并不能创建分支问题

值得注意的是,倘若git项目下没有任何文件可以commit,那么这样子执行也是没有用的,估计是初始的master对象为空无法根据master去创建新分支。

究其原因,是由于刚创建的git仓库默认的master分支要在第一次有效的commit之后才会真正建立,否则就像你声明了个对象但没初始化一样。

评论