git常用命令学习
git入门[🐒都能懂的GIT入门]
在Windows上安装Git
安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
设置成功后可用 git config –l 命令查看结果
创建版本库
- 选择一个合适的地方,创建一个空目录:
$ mkdir learngit $ cd learngit $ pwd /Users/michael/learngit
- 通过
git init
命令把这个目录变成Git可以管理的仓库:$ git init Initialized empty Git repository in /Users/michael/learngit/.git/
如果你没有看到.git
目录,那是因为这个目录默认是隐藏的,用ls -ah
命令就可以看见
把文件添加到版本库
首先,现在我们编写一个readme.txt
文件,内容如下
Git is a version control system.
Git is free software.
一定要放到learngit
目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。
- 用命令
git add
告诉Git,把文件添加到仓库:$ git add readme.txt //添加指定指定单个文件 $ git add * //添加所有文件
- 用命令
git commit
告诉Git,把文件提交到仓库:$ git commit -m "wrote a readme file" [master (root-commit) cb926e7] wrote a readme file 1 file changed, 2 insertions(+) create mode 100644 readme.txt
$ git commit -a -m "wrote a readme file" //全部提交
小结 初始化一个Git仓库,使用git init命令。 添加文件到Git仓库,分两步: 第一步,使用命令git add <file>,注意,可反复多次使用,添加多个文件; 第二步,使用命令git commit,完成。
注意:每次修改,如果不add
到暂存区,那就不会加入到commit
中。
时光穿梭机
-
要随时掌握工作区的状态:
-
$ git status
-
-
如果
git status
告诉你有文件被修改过,查看修改内容:-
$ git diff
-
版本回退
-
HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令:$ git reset --hard commit_id //回退指定版本
$ git reset --hard HEAD^
//上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
-
穿梭前,可以查看提交历史,以便确定要回退到哪个版本,试用命令:
$ git log //完整log
$ git log --pretty=oneline //简便log
-
要重返未来,可以查看命令历史,以便确定要回到未来的哪个版本,使用命令:
$ git reflog
撤销修改
- 撤销工作区修改/删除(未add)
$ git checkout -- file
- 撤销暂存区修改/删除(未commit)
$ git reset HEAD file
- 撤销版本库修改(参考版本回退一节,不过前提是没有推送到远程库)(commit但未push)
删除文件
- 删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
$ git rm file
远程仓库
添加远程库:
- 关联一个远程库,使用命令
:
$ git remote add origin git@server-name:path/repo-name.git
- 推送master分支的所有内容(最新修改版本),使用命令:
git push -u origin master
注:由于远程库是空的,我们第一次推送
master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令(不加-u,即:git push origin master)。 - 分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
从远程克隆:
- 要克隆一个仓库,首先必须知道仓库的地址,然后使用
git clone
命令克隆。 - Git支持多种协议,包括
https
,但通过ssh
支持的原生git
协议速度最快。
分支管理
- 查看分支:
git branch
- 创建分支:
git branch <name>
- 切换分支:
git checkout <name>
- 创建+切换分支:
$ git checkout -b <name> //默认创建本地分支 $ git checkout -b <name> origin //创建远程分支
- 合并某分支到当前分支:
$ git merge <name> (默认
Fast forward
模式) $ git merge --no-ff -m "merge with no-ff" <name> (强制禁用Fast forward
模式)
//请注意:--no-ff
参数,表示禁用Fast forward模式,启用普通merge模式!
//通常,合并分支时,如果可能,Git会用
Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。//如果要强制禁用
Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。因为本次合并要创建一个新的commit,所以加上-m
参数,把commit描述写进去。 - 删除分支:
$ git branch -d <name> //已合并的分支可正常删除 $ git branch -D <name> //未被合并的分支需要丢弃,强行删除
- 看到分支合并图:
$ git log --graph //详细合并图 $ git log --graph --pretty=oneline --abbrev-commit //简便合并图
- bug分支:当手头工作没有完成时,先把工作现场
git stash
一下,然后去修复bug,修复后,再git stash pop
,回到工作现场。
$ git stash //把当前工作现场“储藏”起来,等以后恢复现场后继续工作 $ git stash list //查看储存列表 $ git stash apply //恢复储存的工作现场 //你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash $ git stash apply stash@{0} $ git stash drop //删除储存数据 $ git stash pop //恢复的同时把stash内容也删掉
- 多人协作
-
首先,可以试图用
git push origin branch-name
推送自己的修改; -
如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并; -
如果合并有冲突,则解决冲突,并在本地提交;
-
没有冲突或者解决掉冲突后,再用
git push origin branch-name
推送就能成功!
如果
git pull
提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name
。这就是多人协作的工作模式,一旦熟悉了,就非常简单。
小结:-
查看远程库信息,使用
git remote -v
; -
本地新建的分支如果不推送到远程,对其他人就是不可见的;
-
从本地推送分支,使用
git push origin branch-name
,如果推送失败(说明远程此分支已更新),先用git pull
抓取远程的新提交; -
在本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致; -
建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
; -
从远程抓取分支,使用
git pull
,如果有冲突,要先处理冲突。
-
注:当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
合并分支时,加上--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward
合并就看不出来曾经做过合并。
标签管理
Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
- 创建标签
-
命令
git tag <name>
用于新建一个标签,默认为HEAD
,也可以指定一个commit id;$ git tag v1.0 $ git tag v0.9 6224937
-
git tag -a <tagname> -m "blablabla..."
可以指定标签信息;$ git tag -a v0.1 -m "version 0.1 released" 3628164
-
git tag -s <tagname> -m "blablabla..."
可以用PGP(私钥)签名标签【必须首先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错;如果报错,请参考GnuPG帮助文档配置Key。用PGP签名的标签是不可伪造的,因为可以验证PGP签名。验证签名的方法比较复杂,这里就不介绍了。】$ git tag -s v0.2 -m "signed version 0.2 released" fec145a
-
命令
git tag
可以查看所有标签; - 命令
git show <tagname>
查看标签信息
-
- 操作标签
-
命令
git push origin <tagname>
可以推送一个本地标签; -
命令
git push origin --tags
可以推送全部未推送过的本地标签; -
命令
git tag -d <tagname>
可以删除一个本地标签;【因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。】 -
命令
git push origin :refs/tags/<tagname>
可以删除一个远程标签。【如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除;然后,从远程删除。删除命令也是push,但注意格式】$ git tag -d v0.9 //删除本地标签 $ git push origin :refs/tags/v0.9 //删除远程标签
-
自定义git
- 忽略特殊文件
-
忽略某些文件时,需要编写
.gitignore
; -
.gitignore
文件本身要放到版本库里,并且可以对.gitignore
做版本管理(提交到Git)!忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的
.class
文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
-
- 配置别名(命令缩写)
$ git config --global alias.st status $ git config --global alias.co checkout $ git config --global alias.ci commit $ git config --global alias.br branch //把暂存区的修改撤销掉(unstage),重新放回工作区 $ git config --global alias.unstage 'reset HEAD' //配置一个git last,让其显示最后一次提交信息 $ git config --global alias.last 'log -1' //甚至还有人丧心病狂地把lg配置成了: $ 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" 加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。 --global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
注:每个仓库的Git配置文件都放在.git/config
文件中,别名就在[alias]
后面,要删除别名,直接把对应的行删掉即可。而当前用户的Git配置文件放在用户主目录下的一个隐藏文件
.gitconfig
中,配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置 - 搭建Git服务器