记录和总结在使用Git的过程中碰到的问题和解决办法。
基本使用
使用gitub可以轻松的托管自己的代码,从而可以多处使用且不需要担心代码丢失!而且可以轻松实现团队开发和版本控制,对于学习者来说是相当不错的,具体步骤如下(以下只是常用基础命令,更多高级命令查阅使用):
上传自己的项目至github基本步骤:
- 登录gitbub,并创建一个仓库。github建议每个项目具有readme.md,lisence,gitignore文件。
- 在本地项目使用命令进行操作。
- git init 初始化项目空间,将目录变成git管理仓库
- git add 增加需要提交的文件
- git add *:git会自动把你当前目录所有修改过的文件添加
- git add . :他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
- git add -u:他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add --update的缩写)
git add -A
:是上面两个功能的合集(git add --all的缩写)
- git commit –m “des”提交并描述
- git remote add
指定地址,关联远程仓库,默认名称origin。 - 错误:remote origin already exists.解决:git remote rm origin
- git push –u
master(表示分支),第一次添加-u参数,用了参数-u之后,以后就可以直接用不带参数的git pull从之前push到的分支来pull。 - 示例
git init git add README.md git commit -m "first commit" git remote add origin https://github.com/liuxinqiong/test.git git push -u origin master
- 团队开发
git log查看所有提交信息 git pull拉取远程版本内容 git status 查看当前仓库状态 git diff 文件名 查看指定文件的不同之处 git clone url 克隆仓库
- 分支控制
git branch 查看本地分支 git checkout –b <branch name>创建新分支后检出 git checkout <branch name>切换分支 git merge <branch name>将指定分支和当前分支合并 git branch –d <branch name>删除指定分支
- 配置
注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。git config --global user.name "Your Name" git config --global user.email email@example.com
- 删除本地仓库
rm不接受标准输入,所以不能用find / -name "tmpfile" |rm
find . -name ".git" | xargs rm -Rf
谨记
:苦逼事情发生了,由于我本地的git项目都放在一个dis的文件夹内,有次创建ionic项目,忘记cd进入ionic项目直接在dis文件夹git init
了,事后没注意直接使用上面命令干掉了,后面编辑其他项目时,才发现他把我整个dis文件夹下所有项目的的git管理给删除了,由于对于git高级操作不熟练,出现很多奇怪的问题,真是想哭。建议之用maxdepth 指定只查找当前目录下,不搜索任何当前目录下的所有子目录
。find . -maxdepth 1 -name ".git" | xargs rm -Rf
分支管理
新建分支与切换
新建好的代码库有且仅有一个主分支(master),它是自动建立的。
可以新建分支用于开发:
git branch develop master
新建一个叫develop的分支,基于master分支。
切换到这个分支:
git checkout develop
现在可以在这个develop分支上做一些改动,并且提交。 注意:切换分支的时候可以发现,在Windows中的repository文件夹中的文件内容也会实时相应改变,变成当前分支的内容。
分支push
push方法1:现在如果想直接Push这个develop分支上的内容到github
git push -u origin
如果是新建分支第一次push,会提示:The current branch develop has no upstream branch.
git push --set-upstream origin develop
输入这行命令,然后输入用户名和密码,就push成功了。以后的push就只需要输入git push origin。
push方法2:比如新建了一个叫dev的分支,而github网站上还没有,可以直接:
git push -u origin dev
这样一个新分支就创建好了。
push方法3:提交到github的分支有多个,提交时可以用这样的格式:
git push -u origin local:remote
比如:git push -u origin master:master
- 表明将本地的master分支(冒号前)push到github的master分支(冒号后)。
- 如果左边不写为空,将会删除远程的右边分支。
新建一个分支develop2,同时切换到这个分支
git checkout -b develop2 develop
分支管理
删除分支
git branch可以查看所有的分支
git branch -d develop2 将develop2分支删除
如何批量删除分支
git branch |grep 'branchName' |xargs git branch -D,从分支列表中匹配到指定分支,然后一个一个(分成小块)传递给删除分支的命令,最后进行删除。
合并分支
先转到主分支:git checkout master
然后把develop分支merge过来:git merge --no-ff develop
参数意义:
不用参数的默认情况下,是执行快进式合并。
使用参数--no-ff,会执行正常合并,在master分支上生成一个新节点。
merge的时候如果遇到冲突,就手动解决,然后重新add,commit即可。
问题记载
.gitignore修改之后不生效
一旦项目已经被git管理起来,后期修改的gitignore是不会直接生效的,必须先清空缓存,然后重新添加,再提交.gitignore。语法如下:
git rm -r --cached . #清除缓存
git add . #重新trace file
git commit -m "update .gitignore" #提交和注释
git push origin master #可选,如果需要同步到remote上的话
经测试:gitignore匹配规则必须顶格写,前面不能有空格,否则不会生效。
git pull出错
某种情况就是线上环境代码与本地代码不一致,保留线上环境,不应用本地改动。
git stash
git pull
git stash pop
git stash 可用来暂存当前正在进行的工作, 比如想pull 最新代码, 又不想加新commit, 或者另外一种情况,为了fix 一个紧急的bug, 先stash, 使返回到自己上一个commit, 改完bug之后再stash pop, 继续原来的工作。
文件夹成灰色,无法进入
原因是因为,文件夹中包含其他仓库,所以需要删除其中的.Git 文件。
- 删除其他仓库的Git管理
find . -name ".git" | xargs rm -Rf
- 将原项目文件夹从缓存中删除
git rm -r --cached some-directory
push失败
如果origin的master分支上有一些本地没有的提交,push会失败。
所以解决的办法是, 首先设定本地master的上游分支:
git branch --set-upstream-to=origin/master
然后pull:
git pull --rebase
最后再push:
git push
git地址发生改变
很多时候觉得之前的git仓库名词不合适,修改了名词之后,之前clone的工程push的时候就会提示提示已经改变,请更改地址,命令如下:
git remote set-url origin new_url
git remote –v可以查看当前的远程地址。
风波经历
最近由于乌龙经历,不小心将本地仓库删除了,然后重新创建仓库,然后push代码始终失败。下面记录下修复步骤(当时是这么解决的,但是方案是在是下下策):
- 推送更新:git push
- 状态:rejected
- 提示:因为远程有你本地没有的工作,因此被拒绝,通常原因是其他仓库推送了同一个引用,在推送之前你可能希望首先集成远程修改
- 提示你非快进方式的更新被拒绝了,fast forward能够保证不会强制覆盖别人的代码,确保了多人协同开发。尽量不要使用non fast forward方法提交代码。
- 好像很好解决,拉取更新:git pull,状态:报错
- 没有关联远程分支?那就关联一个:git branch --set-upstream-to=origin/master
- 在网上查到使用 git pull --rebase
- git pull = git fetch + git merge
- 参数--rebase:取消commit + 临时保存为补丁 + 更新内容 + 补丁应用到工作区
- 在rebase的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止rebase并会让你去解决冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:
- git rebase --continue:这样git会继续应用(apply)余下的补丁。
- git rebase --abort:在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。
- 继续git push,提示:你当前不在分支上
- 使用git push -u origin master,提示:更新被拒绝,因为推送的分支落后于服务器副本,建议先集成远程更新在重新提交
- 还不是最新,继续git pull,提示我还有未合并文件,退出是因为有未解决冲突,先fix再add再commit
- 使用git status
- 提示rebase正在进行中,建议在解决冲突后运行git rebase --continue
- git rebase --skip跳过这个补丁
- git rebase --abort检出原始分支
- 没办法冲动的尝试了一下git push -uf origin master,结果很伤心,提交记录被清空了
- git status依旧显示在rebase中
- 使用git push依旧提示不在分支上
- git push -u origin master提示关联(跟踪)远程分支成功,且Everything up-to-date
- git status提示rebase中,提示冲突修复完成后,运行git rebase --continue
- git rebase --continue,提示没有更新,你可能需要跳过这个补丁
- 此时运行git commit,依旧提示rebase进行中
- 运行git rebase --abort,一切似乎美好了,但是提交记录没了,很可惜
- 撤销本地修改:git reset --hard origin/master
其他命令
- 回退n个版本:git reset –hard HEAD~3
- git多用户提交冲突
# 备份当前工作区内容到git栈中,并使当前工作区内容与上次提交时一致 git stash # 拉取最新代码 git pull # 表示从Git栈中读取最近一次保存的内容,恢复工作区的相关内容 git stash pop # 手动merge你之前冲突的文件 git diff -w cn/trinea/appsearch/MainActivity.java