晴明的博客园 GitHub      CodePen      CodeWars     

[cs] git (2)

pull 与 fetch

pull=fetch+merge,pull的话,下拉远程分支并与本地分支合并。
fetch 并没更改本地仓库的代码,只是拉取了远程 commit 数据,将远程仓库的 commit id 更新为latest。

rebase

git rebase用于把一个分支的修改合并到当前分支。

rebase一种情景:

假设你现在基于远程分支"origin",创建一个叫"mywork"的分支。

$ git checkout -b mywork origin

现在在这个分支做一些修改,然后生成两个提交(commit).
有些人也在"origin"分支上做了一些修改并且做了提交了.
这就意味着"origin"和"mywork"这两个分支各自"前进"了,它们之间"分叉"了。
在这里,可以用"pull"命令把"origin"分支上的修改拉下来并且和你的修改合并;
结果看起来就像一个新的"合并的提交"(merge commit).
如果想让"mywork"分支历史看起来像没有经过任何合并一样,可以用 git rebase:

$ git checkout mywork
$ git rebase origin

这些命令会把你的"mywork"分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把"mywork"分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到"mywork"分支上。
当'mywork'分支更新之后,它会指向这些新创建的提交(commit),而那些老的提交会被丢弃。 如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除.

解决rebase冲突

在rebase的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止rebase并会让你去解决 冲突;
在解决完冲突后,用git-add命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:

$ git rebase --continue

这样git会继续应用(apply)余下的补丁。

$ git rebase --skip

跳过,注意此操作中当前分支的修改会直接覆盖目标分支的冲突部分。

在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。

$ git rebase --abort

要注意谁是 ours 谁是 theirs

rebase 和 merge 的区别

git merge:
简单来说,它把两条不同分支历史的所有提交合并成一条线,并在“末端”打个结,即生成一次合并提交。最后形成一条单一的提交线。
git rebase:
根据参数的不同,行为有些差别。但总的来说,它相当于把分叉的两条历史提交线中的一条,每一次提交都捡选出来, 在另一条提交线上提交。最后也形成一条单一的提交线。

最终结果两者历史记录不同。

pull=fetch+merge

git pull --rebase  #等于fetch + rebase

两种方式:
1.本地修改代码后,先stash,然后pull,pop,commit,push
2.本地修改代码后,commit(可多次),然后pull --rebase,push
第2种,本地的commit会在pull的内容的前面,
rebase尽量慎用,可能会导致同伴pull没rebase的版本然后提交冲突问题,自己的本地冲突问题也可能不那么好解决。

rebase交互模式

-i--interactive参数去调用交互模式。
操作对象是那些自最后一次从origin仓库拉取或者向origin推送之后的所有提交。

git rebase -i

#(action) (partial-sha) (short commit message)

stash

git stash 对当前的暂存区和工作区状态进行保存。
git stash list 列出所有保存的进度列表。
git stash pop [--index] [<stash>] 恢复工作进度
git stash apply [--index] [<stash>] 不删除已恢复的进度,其他同git stash pop
git stash drop [<stash>] 删除某一个进度,默认删除最新进度
git stash clear 删除所有进度
git stash branch <branchname> <stash> 基于进度创建分支

找回误删的stash

git stash pop 最后会打印出pop掉的commitid值,若这个记录还存在直接使用即可。
git fsck, 会打印出所有的dangling commit, 悬挂的commit是不被任何branch引用的commit。 一般list出的第一个commit即是刚刚被pop掉的commit。
也可通过查看commit在commit graph中的位置确定对应的commitID.

git stash apply  <commitID>

reset

回滚本地代码

git reset [ --soft | --mixed | --hard ]

--mixed
会保留源码,只是将git commit和index 信息回退到了某个版本.
git reset 默认是 --mixed 模式
git reset HEAD^

--soft
保留源码,只回退到commit 信息到某个版本.不涉及index的回退,如果还需要提交,直接commit即可.

--hard
commit和index 都回回退到某个版本,本地代码也会回退到某个版本.
git reset --hard origin/master

revert

回滚远程代码

git revert [commit id]

git revert用于反转提交,执行revert命令时要求工作树必须是干净的.
git revert用一个新提交来消除一个历史提交所做的任何修改.
revert 之后本地代码会回滚到指定的历史版本,这时再 git push 即可以把线上的代码更新.(不会像reset造成冲突的问题)

reset 是在正常的commit历史中,删除了指定的commit,这时 HEAD 是向后移动了,
而 revert 是在正常的commit历史中再commit一次,只不过是反向提交,他的 HEAD 是一直向前的.

alias shell脚本

git config --global alias.ac '!git add -A && git commit -m ' 
可以将 git add 和 git commit -m 这两条命令合二为一

接下来可以这样使用 git ac "提交信息"
#!/bin/bash

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global alias.mr merge
git config --global alias.rb rebase
git config --global alias.po "push origin"
git config --global alias.pl "pull origin"
git config --global alias.pu "pull upstream"
git config --global alias.alias "config --get-regexp ^alias\." 
git config --global alias.unstage 'reset HEAD'
git config --global alias.last 'log -1'
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" #这个超胖的


# This is for list all aliases
# Cache the credentials for 10 hours the next time you input them
git config --global alias.cache "config --global credential.helper 'cache --timeout=36000'"

echo "List all configured aliases"
git alias

conflict

<<<<<<< HEAD
本分支
=======
被合并分支
>>>>>>> dev

其他

git add -p

#可以一段一段地add,每一段都会问你要不要添加(y/n?)。
git blame [filename]

#会得到整个文件的每一行的详细修改信息:包括SHA串,日期和作者.
git diff master...

#如果用2个点进行diff,会把master的新增代码显示出来。
#用3个点进行diff,只会显示当前分支与master的最近公共祖先与当前分支的差异。
git push -u

#如果当前分支没有设置过track,这个命令会在push的同时,设置track。
git bisect start

#查找坏的branch

垃圾回收

Cleanup unnecessary files and optimize the local repository

git gc
posted @ 2017-07-07 19:16  晴明桑  阅读(219)  评论(0编辑  收藏  举报