Open uniquejava opened 8 years ago
将多个commit合并成一次, 只要将除第一次pick之后的那pick全部替换成s即可。替换成s的commit会自动合并到标记为pick的那一次提交。如下:
执行git rebase -i upstream/master
pick afafafdf232raf
pick 12312321wd
pick afaf23rwef3e
pick 13ewqdwad
要把后面三个pick批量替换成改成s, 可以使用如下快捷命令(将2-4行的pick改成s)
:2,4s/pick/s
:wq
保存后提示有冲突 git status查看冲突的文件有哪些,用webstorm逐个打开这些文件,找到所有的<<<(command + f)
<<<<<HEAD
code on head
======
code on some branch
>>>>>>>SOME_BRANCH
比较===上面和===下面的代码,看哪个是对的。 比如我会command+d(删除行)只留下code on head这一段(表示===上面的这段代码是正确的) 保存,打开下一个冲突的文件。修改所有出现<<<的地方。。。
所有的文件改完后 使用git add .提交变化(相当于svn中的mark as resolved) 然后 git rebase --continue 如果还有冲突, 重复以上步骤,直到git status全部变绿。。
(在任意时候,如果想撤消所有的变更,使用git rebase --abort)
最后git push origin branch_name -f
git checkout origin/master -- router/router.js
git clone https://path/to/xx.git --depth 1 -b branch_name local_dir_name 比如 git clone https://github.com/jquery/jquery.git --depth 1 -b 1.12-stable jq1.x 只保留最后一条history, 只下载1.12-stable分支, 放在当前目录jq1.x这个子目录中.
git add . git add a.txt b.js c.java git add .txt git status -s git diff 比较working directory和index git diff hello.txt 仅比较某个文件 git diff --staged 比较index和最后一次commit git diff HEAD 比如working directory和最后一次commit git commit -a -m "message" 跳过暂存区一键提交 git checkout -- dir_name 撤销对某个目录所做的变更(危险) git checkout -- .log 撤销对某类文件所做的变更(危险) git checkout -- . 撤销对所有文件所做的变更(危险) git reset HEAD hello.txt 从暂时区移除某个文件, git add的逆反操作(安全) rm abc.txt 删除未track的文件 git rm abc.txt -f 从暂存区连同本地一起删除 详见: 这里
git log git log -p -2 快速浏览最近两次commit所带来的变化 git log --stat 查看最近改了哪些文件 git log --pretty=format:"%h - %an, %ar : %s" 指定log格式,类似github commit上看到的内容 git log --since=2.days --oneline 只列出最近两天的 详见: 这里 git log --follow resource/adic/filename.fdic.xml.bak 查看某个文件的变更历史 git show REVISION:/path/to/file 查看某个指定版本下的文件内容 git diff b4d8628^^..b4d8628 resource/adic/filename.xml.bak 比较某次版本变更中某个文件的变化
详见: https://stackoverflow.com/questions/927358/how-to-undo-the-last-commits-in-git
适用于commit了但未push
最常用: git reset HEAD~1
(只保留working area)
完全重置: git reset --hard HEAD~1
最不常用: git reset --soft HEAD~1
(保留index和working area)
git remote -v(显示remote列表) git remote add remote_branch_name url (默认的remote_branch_name为origin) git remote show origin(显示某remote详情) git remote rename origin osc (重命名) git remote rm github (删除某个remote branch) git clone -o osc http://git.oschina.net/~ (不喜欢默认origin时这样clone)
git branch (查看当前所处的branch) git branch -a (列出所有的branch, 包括remote) git branch revert_branch HEAD^(基于某个commit id建新分支) git checkout revert_branch(切换到某个分支) git checkout -b mybranch(基于当前commit id新建branch并切换到新分支) git checkout -b revert-branch HEAD^(基于某commit id新建分支) git branch -d mybranch(删除本地branch) git branch -m old_branch new_branch(重命名本地branch) git merge mybranch(将mybranch合并到当前所在的branch) git push origin mybranch (推送本地branch到远程) git push origin local_branch_name: remote_branch_name) (推送本地branch到远程另一个branch) git push origin :mybranch(删除远程branch)
git checkout xx_tag(切换到xx_tag) git tag v0.1 (给当前版本创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字) git tag -a v1.2 9fceb02 (给某个版本打标签, 后期打标签) git tag -a v0.1 -m "a runnable version." (将当前版本打标签) git tag(列出所有的tag) git tag -l "v0.*" 显示某些tag git show v0.1(显示某个tag) git tag -d v0.1(删除某个tag) git push origin v0.1(将tag v0.1推向服务器) git push origin --tags(将所有的tag推向服务器) git checkout -b version2 v2.0.0 (不能真正的检出标签,只能基于某tag创建分支,如果分支上代码有变更, 注意此时tag和branch代码就不一致了)
如果tag有一个唯一的名字 git tag -d [tag]; git push origin :[tag]
如果tag刚好和branch同名, 则使用下面的命令删除tag.
git tag -d [tag] git push origin :refs/tags/[tag]
见: How do I configure git to ignore some files locally? 见: Git - Difference Between 'assume-unchanged' and 'skip-worktree'
往.gitconfig文件的 [alias] 部分添加一些alias(直接使用下面的命令也可)
git config --global alias.ignore 'update-index --skip-worktree'
git config --global alias.unignore 'update-index --no-skip-worktree'
git config --global alias.ignored '!git ls-files -v | grep "^S"'
现在, 你可以使用如下git ignore命令来管理这些文件了.
git ignore config.xml
git will pretend that it doesn't see any changes upon config.xml — preventing you from accidentally committing those changes.
git unignore config.xml
git will resume acknowledging your changes to config.xml — allowing you again to commit those changes.
git ignored
git will list all the files which you are "ignoring" in the manner described above.
简而言之, assume-unchanged
是为了提高性能, 告诉git, developer永远都不会去修改某个文件(比如SDK文件夹)
skip-worktree
是告诉git, developer会在本地添加/修改某个文件, 求你不要track这个文件(不管是在repo已经存在的还是用户新增), 即使用git reset --hard也不要去覆盖这个文件.
--skip-worktree
针对已经track或未track的文件均有效, 而.git/info/exclude
只对未track的文件有效
git show commit_id git log --oneline --graph git log --oneline -Ssearch_string_here
git config --list 列出所有的配置项
git config user.name 查看某一项配置
git config --global user.name "cyper"
git config --global user.email "3453**@qq.com"
git config --global core.autocrlf true/input (对换行符的处理, windows上设置为true,其它平台设置为input)
git checkout -- file_name (撤销本地的变更,file_name可以是通配符,比如.txt)
git commit --amend 重做最后一次提交
git reset 清空index区(撤销所有的git add)
git reset file_name 撤销单个文件的git add
git reset -i HEAD~3 和 git rebase -continue(每次向下一个commit前进一步)
git diff 比较working directory和index
git diff --staged 比较index和最后一次commit
git diff HEAD 比如working directory和最后一次commit
git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status git config --global alias.unstage 'reset HEAD --' 这会使下面的两个命令等价: $ git unstage fileA $ git reset HEAD -- fileA git config --global alias.last 'log -1 HEAD'
使用git也有两年的时间了。以前带我的同事,让我在拉代码的时候要我使用git pull --rebase,一直很纳闷为什么要那样做,后来遇到拉代码的时候有许多冲突要解决,然后去查找资料,才了解到其中的一些事情。今天分享一下,顺便自己也梳理一下。
git pull
git pull 是 git fetch + git merge FETCH_HEAD
的缩写。所以,默认情况下,git pull就是先fetch,然后执行merge 操作,如果加–rebase 参数,就是使用git rebase 代替git merge。
merge 和 rebase
merge 是合并的意思,rebase是复位基底的意思。
现在我们有这样的两个分支,test和master,提交如下:
D---E test
/
A---B---C---F master
在master执行git merge test,然后会得到如下结果:
D--------E
/ \
A---B---C---F----G test, master
在master执行git rebase test,然后得到如下结果:
A---B---D---E---C'---F' test, master
可以看到,merge操作会生成一个新的节点,之前的提交分开显示。而rebase操作不会生成新的节点,是将两个分支融合成一个线性的提交。
通过上面可以看到,想要更好的提交树,使用rebase操作会更好一点。这样可以线性的看到每一次提交,并且没有增加提交节点。 在我们操作过程中。merge 操作遇到冲突的时候,当前merge不能继续进行下去。手动修改冲突内容后,add 修改,commit 就可以了。 而rebase 操作的话,会中断rebase,同时会提示去解决冲突。解决冲突后,将修改add后执行git rebase –continue继续操作,或者git rebase –skip忽略冲突。
比如我想删除src/assets/bg.png
.
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch src/assets/bg.png' \
--prune-empty --tag-name-filter cat -- --all
详见: https://help.github.com/articles/removing-sensitive-data-from-a-repository/
git commit --amend --author="Philip J Fry <someone@example.com>"
https://makandracards.com/makandra/1717-git-change-author-of-a-commit
写得非常详细: https://stackoverflow.com/questions/3042437/change-commit-author-at-one-specific-commit
Interactive rebase off of a point earlier in the history than the commit you need to modify (git rebase -i <earliercommit>
). In the list of commits being rebased, change the text from pick
to edit
next to the hash of the one you want to modify. Then when git prompts you to change the commit, use this:
git commit --amend --author="Author Name <email@address.com>"
For example, if your commit history is A-B-C-D-E-F
with F
as HEAD
, and you want to change the author of C
and D
, then you would...
git rebase -i B
(here is an example of what you will see after executing the git rebase -i B
command)
A
, use git rebase -i --root
C
and D
from pick
to edit
C
git commit --amend --author="Author Name <email@address.com>"
git rebase --continue
D
git commit --amend --author="Author Name <email@address.com>"
againgit rebase --continue
同时有两条精彩的评论:
--no-edit
参数,. git commit --amend --reset-author --no-edit
这样就不会打开editor. git rebase -i --root
see stackoverflow, One liner, but be careful if you have a multi-user repository - this will change all commits to have the same (new) author and committer.
git config user.name xxx
git config user.email yyy
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='yinsb'; GIT_AUTHOR_EMAIL='yinsb@xx.com'; GIT_COMMITTER_NAME='yinsb'; GIT_COMMITTER_EMAIL='yinsb@xx.com';" HEAD
第一次要使用git pull origin master --rebase
注意针对某个 commit id, cherry-pick会重新生成一个新的commit id, 常用命令如下:
git cherry-pick commit-id (单次)
git cherry-pick from..to (不包含from)
git cherry-pick from^..to (包含from)
git cherry-pick --continue (解决冲突后继续)
git cherry-pick --abort (回到cherry-pick之前的状态)
git cherry-pick --quit (放弃本次commit-id)
git cherry-pick不能直接作用于merge类型的commit, 要加-m参数.
The synopsis is git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
git cherry-pick goes from left to right commit. You can order how you want. If you have a conflict you have three choices. you can git cherry-pick --quit
(stop cherry-picking and let your tree in his current state), git cherry-pick --abort
(stop cherry-picking and reset your branch to the state where he was before you start git cherry-pick) or resolve this conflict with an editor or with git mergetool
and then git cherry-pick --continue
go to next commit in your list.
see https://stackoverflow.com/questions/20698614/multiple-commits-cherry-picking
git submodules ~git cherry-pick~ ~git ignore in depth~ git web hooks
There is no tracking information for the current branch
You could specify what branch you want to pull:
git pull origin master
Or you could set it up so that your local master branch tracks github master branch as an upstream:
git branch --set-upstream-to=origin/master master
git pull
This branch tracking is set up for you automatically when you clone a repository (for the default branch only), but if you add a remote to an existing repository you have to set up the tracking yourself. Thankfully, the advice given by git makes that pretty easy to remember how to do.
很多初次使用者问到的问题link列在这: https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key
cd ~/.ssh
ls
ssh-keygen -o
cat ~/.ssh/id_rsa.pub
如果碰到, 这里有N多解决方案: https://stackoverflow.com/questions/13509293/git-fatal-could-not-read-from-remote-repository
如何应用到多个branch
* 匹配所有分支
[md]* 匹配分支名以m或d开始的
[md][ae]* 匹配分支名第一个字母为m或d, 第二个字母为a或e,这样即能匹配master也能匹配dev.
git reflog 找到曾经正确的那次提交的id: xxxx git checkout xxxx
然后你懂的
It may be more efficient to push delete all the tags in one command. Especially if you have several hundred.
In a suitable non-windows shell, delete all remote tags:
git tag | xargs -L 1 | xargs git push origin --delete
Then delete all local tags:
git tag | xargs -L 1 | xargs git tag --delete
和RTC的比较: Guide to Git for Rational Team Concert users
猴子都能懂的Git: https://backlog.com/git-tutorial/cn/
大量的github文档: https://help.github.com/categories/collaborating-with-issues-and-pull-requests/
两种工作流程: GitHub Flow and Git Flow are the two most common Git patterns.
设置代理
1. github flow
See Understanding the GitHub Flow
又分为两种 Model: Fork & Pull Model, 以及 Shared Repository Model. 详见: About collaborative development models
我们项目用的Fork & Pull Model
还有一种适合小团队用的Shared Repository Model
see GitHub Collaboration Using the Shared Repository Model and the embedded link there.
套路
2. git flow
See A successful Git branching model
关于PR
详见:https://help.github.com/articles/about-pull-requests/
需要特别注意的两点: Note: When working with pull requests, keep the following in mind: