Doc下载: https://download.csdn.net/download/qccz123456/10567652
参考文献:https://www.yiibai.com/git/
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
Linux安装git:sudo apt-get install git
安装完成后配置:
$ git config --global user.name "Your Name"
$ git config --global user.email email@example.com
创建git仓库:
$ mkdir learngit
$ cd learngit
$ git init
添加修改后的文件到仓库:
$ git add file1.txt 或添加所有修改的文件 $ git add .
$ git commit -m "add file."
显示commit的记录:
$ git log 或只输出关键信息 $ git log --pretty=oneline
版本回退:
$ git reset --hard HEAD^(HEAD指当前版本,HEAD^指上一个,HEAD^5指上5个版本)
或 $ git reset --hard commit_id(git log/reflog显示的commitid号,hard回退HEAD、暂存区和工作区)
查看历史操作命令,可回到之前操作的状态:
$ git reflog
Git中的工作区、版本库概念:
工作区(working directory): 电脑中能看到的目录;版本库(repository):有一个.git的隐藏目录。版本库中有stage(或者叫index)的暂存区和分支。git add将work directory文件放到stage中。git commit将stage中文件放到分支中,并此时stage中为空目录。
查看当前工作区working directory和缓存区stage下的状态:
$ git status
查看工作区中文件与HEAD版本库中对应文件的区别:
$ git diff HEAD readme.txt
查看工作区中文件与缓存区中对应文件的区别
$ git diff readme.txt
撤销修改:工作区已修改,但未git add采用如下命令,回到最近一次git commit/add时的状态:
$ git checkout -- readme.txt
工作区已修改,并且已git add采用如下命令:
$ git checkout HEAD -- readme.txt
通常git checkout用于撤销工作区的修改,而git reset用于撤销git add/commit的修改。
删除版本库中的文件:
$ git rm test.txt
$ git commit -m "remove test.txt"
若工作区、缓存区、版本库都不一致,想撤销工作区中的修改,相对于master库:
第一步撤销缓存区中的修改:$git reset HEAD readme.txt
第二步撤销工作区中的修改:$git checkout -- readme.txt
远程库:
上传本地SSHKey到git服务器,命令行运行以下命令,在用户主目录的.ssh目录找到id_rsa.pub,复制粘贴到git服务器SSHKey页面:
$ssh-keygen -t rsa -C "youremail@example.com"
在网页上或其他方式创建好远程库origin后,使用git remote命令将本地库关联到远程库origin,第一次推送master分支到origin时,git push –u命令,之后推送可以不加-u:
$ git remote add origin git@server-name:path/repo-name.git
$ git push -u origin master
$ git push origin master
$ git push origin HEAD:originName (git push <远程主机名> <本地分支名>:<远程分支名>)
克隆远程仓库到本地:
$ git clone git@server-name:path/repo-name.git
分支管理:
查看分支:$ git branch(*表示当前所在的分支)
创建分支:$ git branch dev
切换分支:$ git checkout dev
创建+切换分支:$ git checkout -b dev
在本地创建远程库下的分支,名称最好一致:$ git checkout -b branch-name origin/branch-name
合并指定分支到当前分支:$ git merge dev
删除分支:$ git branch -d dev
当merge分支时,出现冲突CONFLICT(两个分支中的同一文件中的内容不一致),通过git status查看冲突所在的文件,打开文件并对冲突部分进行修改,如更换<<<<<<<,>>>>>>>它及其之间的内容,然后使用git add 和commit提交,自动合并完成,最后查看log和删除分支。
$ git log --graph --pretty=oneline --abbrev-commit
merge分支时,默认采用Fastforward模式,删除分支后,会丢掉分支信息,并没有丢失commit信息。可采用--no-ff命令禁止该模式,并用-m添加新的commit记录:
$ git merge --no-ff -m "xxxxxx" dev
分支策略:master用来发布新版本,平时不在上面干活,干活分支应该是dev,要发布了才将dev合并到master分支上,并且每个人都有来自dev上的分支,并往dev上合并。
当手头工作没完成,需要保存当前工作现场,并去修复其他bug时,采用gitstash命令保持当前工作区,非暂存区,bug修改完成后,参看stash中保存的list,使用git stashapply[drop]或pop恢复对应的工作(apply,工作恢复后stash内容不删除,使用drop删除;pop恢复并自动删除stash)。
$ git stash
$ git stash list
$ git stash pop stash@{0}
开发新feature或修复bug,最好新建一个分支,若要删除一个没有被合并过的分支,通过下列命令强行删除:
$ git branch -D <name>
查看远程库:$ git remote 或显示更详细的信息 $ git remote -v
推送本地分支到远程分支:$ git push origin branch-name
若因远程库已修改而push失败,需要先gitpull把最新的修改抓下来,如果合并有冲突,则解决冲突,并在本地提交,无冲突后再次push。若本地分支和远程分支之间没有建立关系,应一下命令建立连接:
$ git branch --set-upstream branch-name origin/branch-name
标签tag是指向某个commit的指针,与commit绑在一起,用于标记重大记录。
查看已打标签:$ git tag
给某个commit打标签,标签为本地标签:
$ git tag v1.0(默认是最新的commit)
$ git tag v0.9 6224937(数字是commit id)
$ git tag -a v0.1 -m "version 0.1 released" 3628164(-a标签名,-m说明文字)
显示某个标签具体信息:$ git show v0.1
推送某个标签到远程库:$ git push origin v1.0 或推送所有标签 $ git push origin --tags
删除某个本地标签:$ git tag -d v0.1
若标签已推送到远程库,需要先删除本地标签,再删除远程标签:
$git tag -d v0.9 $ git push origin:refs/tags/v0.9
想参与别人的项目,并希望能修复bug或开发新特性,可在github上点击fork,即在你的账号下clone了一个对方的库,然后将自己账号下的库clone到本地,进行修改,最后希望将修改后的代码推送给对方,需要发起pullrequest。
忽略特殊文件:
在Git工作区的根目录下创建.gitignore文件,写入要忽略的文件名,并提交,Git就会自动忽略这些文件。Github已经准备好了大多数的配置文件:https://github.com/github/gitignore
若需强制添加某被忽略的文件:$git add -f xxx.ini
为命令设置别名:
$ git config --global alias.lg "log --color --graph--pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(boldblue)<%an>%Creset' --abbrev-commit"
即使用git lg替代了git log –color…一大串。
搭建私有的Git服务器:
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000
管理公钥:管理几百号人的公钥,可用Gitosis。
管理权限:git不支持某个文件/目录等的权限控制,可用Gitolite。
修改最近一次commit 的注释:git commit --amend,不能将push后的commit进行修改,对还在本地的commit修改。
合并多个commit:git rebase -i xxxx,如下将某些连续的commit进行合并,通过-i选择某个commit的基准,该基准是不变的,是不会被合并的,被合并的是下一个commit。
$ git lg
* b464870-(HEAD -> master) 3 gitignore
* f24b417- 3
* a6359fd– 1
$ git rebase -i a6359fd
Pick f24b4173 | Pickf24b417 3 | [merge info]
Pick b4648703 gitignore | s b4648703 gitignore | [merge info]
$ git lg
* c0ca138-(HEAD -> master) 3 gitignore
* a6359fd -1
git config --global core.editor "vim" export GIT_EDITOR=vim
git cherry-pick 需要部分代码变动(某几个提交):http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html
git fetch与git pull区别: git pull = git fetch + git merge
difference between origin/branch_name and branch_name?
You have to remember that there are different types of branches:
- (Purely) local branches, i.e. branches you commit to,
- Branches that live in a remote repository, for lack of a better term. You may know the remote repository in question under a remote name, such as
origin
. From that repository's point of view, though, such a branch is local. Welcome to Distributed Version Control!:)
- Remote-tracking branches. Also simply called remote branches, as in the Pro Git book, but I find this phrase confusing; remote-tracking branch is more accurate. They're special local branches whose sole purpose is to reflect the state of branches that live in a remote repositoryat the time of your last communication with the server. In particular, you can't commit to branches of this type.
Here, branch_name
is a local branch, whereas origin/branch_name
is a remote-tracking branch; it reflects the state of the corresponding branch that lives in origin
.
Right after running
git fetch
the remote-tracking branch origin/master
and the corresponding branch that live in origin
should be perfectly in sync (modulo concurrent pushes to the remote server, of course). It shouldn't be a surprise, then, that
git push origin origin/branch_name
doesn't push anything: you're essentially attempting to push stuff that is already present in the ancestry of the corresponding branch that live in origin
.
However, if your local branch, branch_name
, is ahead by one or more commits,
then running
git push origin branch_name
will push the commits contained in branch_name
but not in the branch that live in origin
:
从远程仓库拉repo后,需要再本地创建branch,才能上传到远程仓库:
- Create a new branch:
git checkout -b feature_branch_name
- Edit, add and commit your files.
- Push your branch to the remote repository:
git push -u origin feature_branch_name