git操作大全,值得收藏

Git
一个实现项目版本控制的软件,通过快照保存代码修改部分而非简单复制

正常流程:

1.github上创建新项目

2.初始化本地
git init
git add . (注:别忘记后面的.,此操作是把Test文件夹下面的文件都添加进来)
git commit -m "提交信息" (注:“提交信息”里面换成你需要,如“first commit”)

3.关联远程
git remote add origin git@github.com:dragon0486/notebook.git
git pull --set-upstream origin master
git branch --set-upstream-to=origin/master
如果名字不同,可能还得git pull --allow-unrelated-histories

4.git push (注:此操作目的是把本地仓库push到github上面,此步骤需要你输入帐号和密码)

本地推送到远程仓库

git init cd到当前项目根路径下

git remote add origin 项目地址 如果是本地创建的项目,这步可以提交给github创建一个项目,origin是项目地址的别名

git add .
git commit -m ''

git pull origin master --allow-unrelated-histories
git push origin master --set-upstream origin master # 提示密码时直接回车
git push --set-upstream origin master
git pull --allow-unrelated-histories

git config user.email "chenzl@akulaku.com" 邮箱
git config user.name "dragon0486" 用户名

git config credential.helper store # 设置这个后,输入一次账号密码以后就无需了


生成ssh

1 删除.ssh文件夹(直接搜索该文件夹)下的known_hosts(手动删除即可,不需要git)
2 在下载好的Git中的bin目录下打开bash.exe输入命令ssh-keygen -t rsa -C "username"
(注:username为你git上的用户名)
3 然后找到系统自动在.ssh文件夹下生成两个文件,id_rsa和id_rsa.pub,用记事本打开id_rsa.pub将全部的内容复制。
4 打开https://github.com/,登陆你的账户,进入设置(Settings)找到
5 然后将你复制的内容粘贴到key中
6 仍然在bash.exe中输入ssh -T git@github.com

私钥放到/home/czl/.ssh/id_rsa


版本管理

1.初始化
选择一个合适的地方,创建一个空目录:
$ mkdir git_trainning
$ cd git_trainning/

$ git init

初始化后多了一个.git的目录,这个目录是Git来跟踪管理版本库的
2.把文件添加到版本库
git add first_git_file.txt # 放到暂存区

git commit -m "commit my first git file" #提交到当前分支。

commit前可以git status查看哪些未提交

3.回滚
1. # 修改后,回滚到未提交前修改后add前
git checkout file -- readme.md
git checkout # 切换到另一个分支
2. # 修改并add后,回滚到未提交前修改后add前,将暂存区的修改撤销掉,重新放回工作区
git reset HEAD file #用HEAD时,表示最新的版本。

3. # commit后,回滚到修改并add后commit前
git reset --soft HEAD^ 回到修改后add后commit前

4. # commit后,回滚到修改后add前
git reset --mix HEAD^

5. # commit后,回滚到修改前,把当前版本回退到上一个提交版本,修改前
git reset --hard HEAD^

例子:
git reset --hard 4459657 # 回到指定版本,一定要有版本号commit id,写前六位即可

git reflog # 每一次命令,可以撤销回退
git log # 查看基于当前版本的所有提交
git log --pretty=oneline

概念:
.git是Git的版本库。stage(或者叫index)称为暂存区,Git自动创建的第一个分支master,
以及指向master的一个指针叫HEAD

4.撤销修改
git reset HEAD file #已add, 回到add前但修改后
git checkout -- file #未add前才能回滚到修改前,已add要用上面的命令回撤

# 如果已commit,只能reset --hard了

5.本地仓库提交到github

git remote add origin http:// #

git push -u origin master

分支管理

1.下载最新master
2.把主库代码与本地代码合并
3.提交合并代码到主库

创建dev分支并切换
git checkout -b dev # 相当于git branch dev git checkout dev

创建远程的分支到本地
git checkout -b dev origin/dev

指定本地dev分支与远程origin/dev分支的链接
git branch --set-upstream-to=origin/dev dev


查看分支

git branch

创建,拷贝所有代码
git branch dev

切换
git checkout dev

删除
git branch -d dev

# 未提交的修改,在分支和master都能看到,提交后只能在提交的分支上看到。
# 如果当前分支新增其他分支已存在的文件,提交前不能切换分支,会冲突

创建远程分支(本地分支push到远程): git push origin [name]
删除远程分支: git push origin --delete Chapater6
拉取远程仓库: git pull origin czl:czl


更新master代码

方式一:
git pull [origin master\dev] # git pull --allow-unrelated-histories

#包含了git merge dev 合并分支代码到master,如果不同会报错,打开文件会有不同的地方提示,软件beyond compare

合并后再add提交并push

# 如果GitHub更新了,但本地commit的是还没合并的但修改了,会push不了。

# 先pull,提示哪些更新了,本地文件会有提示,再手动修改更新的地方再push
方式二:
先 git fetch origin master 然后 git merge origin/master 再 git push origin master
方式三:先 git fetch origin master 然后 git rebase origin/master 再 git push origin master

# 三者都可以完成合并并提交新功能,但是日志记录会有差异,如:前两者版本记录中会出现合并,
# 而第三种rebase可以保证版本记录干净整洁。

分支策略
master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
dev分支是不稳定的,每个人都有自己的分支,时不时地往dev分支上合并就可以了


bug分支

1.先把当前工作现场“储藏”起来,回到修改前
git stash
2.切到主分支上,生成一个bug分支,这样就会复制master的内容
git branch -b
3.修改bug
4.提交 add commit
5.切换到master主分支
6.pull看看master有没有更新
git pull origin master
7.git merge bug看看
8.手动合并修改内容,然后add,再commit
9.提交bug修复
git push origin master
10.恢复工作现场,删除bug分支 # 恢复时这期间的修改会自动检测并合并
git stash list # 暂存记录
git stash apply # git stash apply stash@{0}
git stash drop # 删除stash内容
git stash pop # 恢复的同时把stash内容也删了

git branch -d issue-101

git remote #远程仓库的默认名称
git remote -v

pull request
推送修改给作者

忽略上传文件
.gitignore文件 # https://github.com/github/gitignore
git add -f App.class #用-f强制添加到Git
git check-ignore -v App.class #需要找出来到底哪个规则写错了

规则:
以斜杠“/”开头表示目录;

  以星号“*”通配多个字符;

  以问号“?”通配单个字符

  以方括号“[]”包含单个字符的匹配列表;

  以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

擦除ignore文件添加前git追踪的文件(但历史还存在): git rm --cached --force -r .idea然后git commit提交操作(pycharm可能没显示)
git rm --cached fileName执行该命令后, git不再跟踪fileName, 但是fileName文件仍保留
git rm -f fileName执行该命令后, git不再跟踪fileName, 同时fileName文件被删除

gitlab

多人协同开发:合作者、创建组织

代码review分支
组长
其他:
免密码:
http://用户名:密码@github....

版本:
git tag -a v1.0 -m '版本介绍' 本地创建Tag
git show v1.0 查看
git tags -n 查看本地Tag
git tag -l 'v1.4.2.*' 查看本地Tag,模糊匹配
git tag -d v1.0 删除Tag
git push origin :refs/tags/v0.2 更新远程tag
git checkout v.10 切换tag
git fetch origin tag V1.2

git push origin --tags
git pull origin --tags

git clone -b v0.1 项目地址 # 复制指定版本

多久合并:
一个小功能合并一次


git merge --abort 回到merge后出现冲突merge前

上传出现The remote end hung up unexpectedly
git config http.postBuffer 524288000

拉取远程分支并本地新建:
先删除
git fetch origin dev
git checkout -b dev origin/dev # 创建并建立连接
或者git checkout --track origin/v1.0.0-usermanager
git pull origin dev

账号密码设置问题
1. git config --global credential.helper store
输入一次即可
2.上传ssh公钥,然后通过ssh url拉取

github private项目如何更新
1.先fork项目到自己github下
2.源项目如何同步更新?
git remote add apulis git@github.com:apulis/az_tools.git
git remote add apulis https://github.com/apulis/ImageEditing.git
git pull apulis master

git remote -v查看所有的连接

拉取分支
git checkout -b r1.4 origin/r1.4
merge 本地分支
push origin 分支
再pull request融合

如果别人项目的新分支
git checkout -b dev_huawei
git push --set-upstream origin dev_huawei
git pull apulis dev_huawei

远程分支更新了如何更新fork的
git checkout dev
git pull apulis dev
git push

git stash pop后发生冲突
git reset --merge返回stash内容,可以再次pop

回滚到commit前
git reset --soft HEAD~1

github提交后回退分支
git reset --hard commit_id(commit字符)
git push --force

注意其他人将本地的修改回退:
git reset --hard origin/master

Dockerfile配置账号密码
RUN git clone https://username:password@github.com/username/repository.git

https://token@github.com/username/repository.git

LFS(Large File Storage)
将你所标记的大文件保存至另外的仓库,而在主仓库仅保留其轻量级指针.那么在你检出版本时,根据指针的变化情况下更新对应的大文件.而不是在本地保存所有版本的大文件

git lfs install 开启lfs功能
git lfs track 命令进行大文件追踪 例如git lfs track "*.png" 追踪所有后缀为png的文件
git lfs track 查看现有的文件追踪模式

提交代码需要将gitattributes文件提交至仓库. 它保存了文件的追踪记录
提交后运行git lfs ls-files 可以显示当前跟踪的文件列表
将代码 push 到远程仓库后,LFS 跟踪的文件会以『Git LFS』的形式显示:
clone 时 使用'git clone' 或 git lfs clone均可


git拉取不了远程新的分支:
查看所有的分支:
git branch -a
还是查看不了
原因:
git clone --single-branch拉取后的.git/config目录设置了
fetch = +refs/heads/no_network:refs/remotes/origin/no_network
修改为:
fetch = +refs/heads/*:refs/remotes/origin/*


修改远程源:
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
git branch --set-upstream-to=origin/develop develop

一般情况下不用手动一个个branch来set-upstream
极个别情况需要

删除远程分支:
git push origin --delete [branch_name]

需要不是default和protected才行

新的空项目推送:
git remote rename origin old-origin
git remote add origin git@git.i.coolpad.com:chenzenglong/sample.git
git push -u origin --all
git push -u origin --tags

删除某个文件的history:
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" --prune-empty --tag-name-filter cat -- --all

git push --force注意这时候与remote不同,需要force推送,会将remote的改动清空

# 如果是最近的改动,还可以指定最近30次
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch cvat/apps/documentation/static/documentation/assets/car.gif" HEAD~30..HEAD

--env-filter 需要重写作者/提交者名称/电子邮件/时间环境变量
--tree-filter 重写树及其内容的过滤器。该参数在shell中用工作目录设置为检出树的根来评估。然后使用新的树(新文件自动添加,消失的文件会自动删除。.gitignore文件和其他忽略规则不会有任何影响!
--index-filter 重写索引的过滤器。它类似于树型过滤器,但不检出树,这使得它更快。经常使用git rm --cached --ignore-unmatch ...
--msg-filter 重写提交消息的过滤器。参数在shell中使用标准输入的原始提交消息进行评估; 其标准输出被用作新的提交消息。
--tag-name-filter 重写标签名称的过滤器。传递时,将调用指向重写对象(或指向重写对象的标记对象)的每个标记ref。原始标签名称通过标准输入传递,新标签名称预计在标准输出上。
--subdirectory-filter 结果将包含该目录(并且仅包含该目录)作为其项目根目录。意味着重新映射到祖先。

如何推送所有remote到另一个remote?
git pull origin --all
git push czl --all # 只会推送本地存在的branch
git push czl refs/remotes/origin/*:refs/heads/*

tag管理:
切换:
git tag
git checkout tag_name 切换,git 可能会提示你当前处于一个“detached HEAD" 状态。(detached 分离的)
创建:
git tag tagName # 没有注释
git tag -a tagName -m "my tag"
推送:
git push origin tagName
删除:
git tag -d v20190514
git push origin :refs/tags/v20190514

rebase命令:
会合并之前的commit历史

优点:得到更简洁的项目历史,去掉了merge commit
缺点:如果合并出现代码问题不容易定位,因为re-write了history

改变基:
git checkout dev #切换到dev分支 (dev分支有全新的单独改动)
git rebase master #将master最新的commit作为基,把branch1的代码在master重新一个一个提交一下,生成新的commitId,相当于,我把代码又重新在master分支提交一遍 (假设master上改动落后,或者有其他新的改动)

合并时如果出现冲突需要按照如下步骤解决:
修改冲突部分
git add
git rebase --continue
(如果第三步无效可以执行 git rebase --skip)
效果:
commits的基会变为master
后续:
git checkout master
git merge 其他分支 这个时侯并不是在merge代码,而是把HEAD指针移动到最新位置而已。(因为基变化了),如果有分叉,说明master基更新了,需要再次rebase
其他用法:
在master上执行git rebase 待合并的分支 这样也可以避免merge
合并提交记录
git show-branch --more=4 #查看四次提交记录,将这四次提交的合并为一个提交,提交信息整合一下,改成"four commit"
git rebase -i master~ // git rebase -i HEAD~4
显示内容如下:
pick 92ae9c4 second commit
pick 0985eec third commit。 挑选这个作为后面commits合并的commit,后面的commit都改pick为s
pick 5bd480c four commit
保存退出后,又会打开一个vim编辑器窗口
选择注释哪些commit信息,可以新增comment
可能会发生冲突
解决
git add
git rebase --continue
最后完成rebase
git push origin lcoal_branch:my_remote_new_branch

如何校验差距:
git diff origin/master..master --no-prefix -U1000 > xxx.diff
参数:
--no-prefix可以去掉分支前缀
-U1000显示合并后的相同代码地方的行数,更多方便查看上下文。
..表示vs分隔开前后两个对比的分支。


推送到远程指定分支:
git push origin lcoal_branch:my_remote_new_branch


 
上一篇:git commit --amend 使用


下一篇:BGP第三次实验