因为Git是分布式版本控制系统,所以,每个机器提交时都必须自报家门,可以使用如下命令设置你的名字和Email地址
#这个命令,会在"~/.gitconfig"文件中添加信息
#--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来
#将当前目录变成Git可以管理的仓库,命令执行后,当前目录下多了一个.git隐藏文件
git init
将文件添加到暂存区
git add 文件名
将暂存区所有文件提交到当前分支
#如果不执行git add,而直接执行git commit,那么修改内容不会被提交。也就是说git commit只负责把暂存区的修改提交到本地库
git commit -m "本次提交的说明"
#同时完成git add和git commit两个操作
git commit -am README.md
从近到远显示提交日志
#1. 由近到远记录了commit id、作者、提交时间、提交摘要等内容
#2. commit id相当于一个索引key,通过这个索引可以找到历史记录对应的具体内容
#3. 当历史记录过多,一页装不下,会分页,最后一行显示":",此时点击空格,翻到下一页,按b,翻到上一页,按q退出,如果到尾页,会显示"END"
git log
#4. 当条数过多后,查看比较费劲,可以将日志信息格式化后展示,此处表示将每次提交的信息,只用一行展示
git log --pretty=oneline
#5. 一行展示,且只保留commit id的后七位
git log --oneline
#6. git log命令无法查看当前版本之后的commit id信息,这就导致如果通过git reset命令恢复到历史某个版本后,git log无法再查看其之后版本的信息
#7. 而git reflog命令可以,且提供了commit id的后七位与HEAD@{数字}的对照关系,数字表示回到对应commit id的历史版本需要几步
git reflog
还原到指定版本
#1. HEAD指向当前分支master的最后一次提交
#2. HEAD^指向当前分支master的上一次提交
#3. HEAD^^表示上两个,HEAD~100表示上100个
#4. hard参数表示,当本地库指针移动后,强制重制暂存区和工作区,防止他们之间不一致,一般只用hard不用mixed和soft
git reset --hard 67c8975
git reset --hard HEAD^
git reset --hard HEAD~100
#5. mixed:本地库指针移动后、重置暂存区,但工作区代码不变
git reset --mixed 67c8975
#6. soft:本地库指针移动后,暂存区、工作区都不发生变化
git reset --mixed 67c8975
比较工作区、暂存区、指定版本
#1. git是以行为单位管理变更的,当修改某行数据时,都是先删除该行,再重新添加一行,diff命令查出的内容中"-"就表示删除的行,"+"就表示新增的行
#1. 比较工作区与暂存区
git diff
#2. 比较指定文件
git diff 文件名
#3. 比较工作区与指定版本(已commit中内容)
git diff HEAD/${commit id}
#4. 比较暂存区与指定版本(已commit中内容)
git diff --cached HEAD/${commit id}
撤销工作区的修改
git reset --hard
作用相同#如果不加"--"",就变成了"切换到另一个分支"的命令
git checkout -- readme.txt
从版本库中删除文件
#1. 先在工作区删除,如果此步骤为误删,可以使用上面介绍的git checkout -- readme.txt恢复工作区内容
rm test.txt
#2. 在暂存区中提交删除,此处使用git add test.txt也可以
git rm test.txt
#3. 提交到版本库
git commit -m "remove test.txt"
查工作目录和暂存区的状态,和git log区别在于,后者用于查看commit的信息,前者用于查看当前目录与最新版本的区别,以及暂存区与最新版本的区别
git status
git checkout origin/master
命令查看新创建的这个分支,是否和远程库中内容一致,之后执行merge操作将origin/mater分支与master分支进行合并。使用https的url或ssh的url都可以将远程项目克隆到本地
使用https克隆时,每次push操作都需要重新输入github用户名和密码(windows10下可能会记录用户名和密码,不必每次输入)
使用ssh克隆时,push操作不需要输入github用户名与密码,但使用ssh克隆时,需要在克隆之前先配置和添加好ssh key,而只有项目拥有者本人才能添加ssh key
可以先使用自己电脑创建ssh key公钥和私钥,然后将公钥告诉给github,这样,就可以在自己的电脑上,通过ssh协议,使用私钥来访问github的服务器了
本机创建创建一个 SSH key
#-t 指定密钥类型,默认是 rsa ,可以省略。
#-C 设置注释文字,比如邮箱。
#-f 指定密钥文件存储文件名,默认文件名为id_rsa(私有密钥)和id_rsa.pub(公开密钥)
#邮箱为注册github使用的邮箱
ssh-keygen -t rsa -C "[email protected]"
#Generating public/private rsa key pair.
#Enter file in which to save the key
#(/Users/your_user_directory/.ssh/id_rsa):
#按回车键
#Enter passphrase (empty for no passphrase):
#输入push文件的时候要输入的密码,可以不输密码直接回车
#Enter same passphrase again:
#再次输入密码
github上添加公开密钥,今后就可以用私有密钥进行认证了,在SSH Keys中粘贴 id_rsa.pub 文件里的内容
cat ~/.ssh/id_rsa.pub
修改私钥密码
cd ~/.ssh
#修改私钥,执行命令后提示输入密码,两次都直接回车就可以去掉密码,去掉密码后,git push就不再需要输入密码
ssh-keygen -p -f id_rsa
Create repository
#1. 此处也可以使用https协议克隆
#2. 克隆后,git会自动把本地的master分支和远程的master分支对应起来了,且为远程仓库创建别名,别名默认为origin
#3. A克隆了B的远程库后,是没有push权限的,需要由B邀请A才能拥有权限,具体流程为,B进入github--Settings--Manage access--输入要A的github账号--复制邀请链接,然后B将该邀请链接发送给A,A在浏览器中输入该邀请链接后接受邀请,之后A就获取了push权限
git clone [email protected]:michaelliao/gitskills.git
#查看远程库信息
git remote
#查看远程库详细信息,如果没有推送权限,就看不到push的地址
#origin [email protected]:michaelliao/learngit.git (fetch)
#origin [email protected]:michaelliao/learngit.git (push)
git remote -v
#删除远程库
git remote rm origin
#1. 创建本地库
#2. 在github上创建仓库
#3. 在本地创建远程库地址的别名,origin为别名,可以人为指定
#1. 注意michaelliao必须是自己的仓库,如果是别人的,虽然能加上,但push不上去,因为你的SSH Key公钥不在他人的账户列表中
git remote add origin [email protected]:michaelliao/learngit.git
#4. 将本地库中master分支推送到远程库origin上,这样,二者就建立起了联系
git push origin master
#5. 拉取也可以建立联系
git pull origin master
版本控制过程中,可以使用多条线同时推进多个任务,这里面说的多条线就是多个分支。每当需要新开发一个独立功能时,为了防止新功能对原功能有影响,通常开辟一个新分支
分支的好处:同时多个分支可以并行开发,互不耽误,互不影响,提高开发效率,如果有一个分支功能开发失败,直接删除该分支即可,不会对其他分支产生任何影响
每次提交,git都把它们串成一条时间线,这条时间线就是一个分支。之前的操作中,只有一条时间线,在git里,这个分支叫主分支,即master分支
一开始的时候,master分支是一条线,master指向最新的提交,HEAD指向master,这样就能确定当前分支,以及当前分支的提交点
查看分支
#查看分支名称、最后一次commit id、摘要,*表示当前所在分支
git branch -v
创建与切换分支
#1. 创建分支feature-A
git branch feature-A
#2. 切换到feature-A分支
#1. 切换到新分支后,通过git add、git commit就会在新分支上提交更新
#2. 在A分支修改文件并提交后,切换为原来的master分支后,是看不到修改内容
git checkout feature-A
#3. 创建并切换到feature-A分支
git checkout -b feature-A
#4. 快速切回到上一个分支
git checkout -
#5. 由于git checkout和上面撤销工作区的修改命令重复,因此最新版本的Git提供了新的git switch命令来切换分支
#切换分支
git swtich dev
#创建并切换分支
git switch -c dev
删除分支
#5. 删除分支
git branch -d feature-vulcan
#6. 强行删除未被合并过的分支
git branch -D feature-vulcan
合并两个分支
#1. 现要将dev分支合并到master分支上,需要先切换回master分支
git checkout master
#2. 将dev合并到master上
git merge dev
–no-ff合并分支
假设当前分支信息如下
A---B---C feature
/
D---E---F master
执行git merge feature
命令时,只会简单地把指针右移,叫做"快进"(fast-forward),合并后结果如下
A---B---C feature
/ master
D---E---F
而如果使用git merge --no-ff feature
命令禁止快进式合并,合并后结果如下,也就是会产生一个新的提交
A---B---C feature
/ \
D---E---F-----------G master
快进式合并会把feature的提交历史混入到master中,搅乱master的提交历史。但如果你根本不在意提交历史,也不爱管 master 干不干净,那么 --no-ff
其实没什么用。不过,如果某一次 master 出现了问题,你需要回退到上个版本的时候,比如上例,你就会发现退一个版本到了 B,而不是想要的 F,因为 feature 的历史合并进了 master 里
图表形式查看分支的合并情况
git log --graph
与远程库中分支建立关联:可以将远程库中的某个分支设为本地仓库中的某个分支的上游,这样之后,git push
、git pull
命令就不需要再加参数,默认会向当前分支的上游分支去进行push
和pull
#1. 方案一:push的同时添加上游分支,比较常用,且如果远程库中当前没有master分支,就必须使用这个命令,为远程库建立分支的同时,设定上有游分支
git push -u origin master
#2. 克隆后,默认情况下本地只有master分支,如果需要其他分支,需要创建远程origin的dev分支到本地
git checkout -b dev origin/dev
#3. 方案二:直接与远程服务器上的dev进行关联
git branch --set-upstream-to=origin/dev dev
不同分支,对同一文件,同一位置,进行了修改与提交,当想进行merge操作时,就会产生冲突
#1. 由于当前master分支和feature1分支都修改了readme.txt文件的同一位置,尝试将feature1合并到master上时,提示Merge conflict in readme.txt,产生冲突
git merge feature1
#2. 查看冲突的文件
git status
#3. 冲突文件中,两个分支的文件中间由==========隔开,需要人为修改冲突文件,决定保留哪部分内容,之后将冲突文件add、commit
当向远程库中push代码时,也可能会产生冲突,此时就需要先从远程库pull下来最新内容,此时就获取到了冲突文件,对冲突文件修改后(冲突解决方式和本地一样),再push即可
如果再当前的feature-A做了修改,且当前修改内容与master最新版本中内容冲突,此时是无法切换到master分支,会报错
但如果此时急需切换回master分支,解决一个致命的bug,此时可以使用git stash把当前分支的"工作现场""储藏"起来,等以后bug解决后,再恢复"工作现场"并继续工作
git stash储藏的内容可以为任何分支使用,保存的内容包括工作区与暂存区新增的内容
执行git stash后,git status查看工作区与暂存区,会发现没有任何内容,表示当前工作区、暂存区,和上一版本没有任何区别
#1. stash命令可以执行多次,下面命令可以查看stash储藏的所有历史内容
git stash list
#2. 恢复
git stash apply
#3. 删除
git stash drop
#4. 恢复并删除
git stash pop
#5. 恢复到指定的某次stash,stash@{0}为git stash list中查出的stash版本号
git stash apply stash@{
0}
解决完master上的bug后,切回到feature-A,并使用git stash恢复了feature-A,但此时feature-A内容是从master来的,它其实也存在着master中修复的那个bug,该bug在feature-A中尚未被修复,可以使用git cherry-pick 4c805e2
复制一个特定的提交到当前分支,要注意这次提交的hash值,和修复bug时提交的hash值不同,这两个commit只是改动的内容相同,但是两个不同的commit
标签是打在提交上的
打标签
#1. 为HEAD指向的当前分支的当前版本打标签
git tag v1.0
#2. 为指定commit id内容打标签
#a. 先找到历史的commit的id
git log --pretty=oneline --abbrev-commit
#b. 对id值为f52c633的commit打标签
git tag v0.9 f52c633
#3. 创建带有说明的标签,-a指定标签名,-m指定说明文字
git tag -a v0.1 -m "version 0.1 released" 1094adb
查看标签
#1. 查看所有标签,标签内容按字母排序,而不是时间
git tag
#2. 查看打了指定标签的提交
git show v0.9
删除标签
git tag -d v0.1
默认情况下,标签信息都只存储在本地,不会自动推送到远程,可以使用命令将标签推送到远程
git push origin v1.0
#一次性推送全部尚未推送到远程的本地标签
git push origin --tags
删除标签
#如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除
git tag -d v0.9
#然后,从远程删除
git push origin :refs/tags/v0.9
有时某些文件会被放到git工作目录中,但又不想提交它们,比如保存了数据库密码的配置文件、UE修改后保留的备份文件等
每次git status
都会显示Untracked files,影响使用
可以编辑.gitignore文件,从而让git不对这些文件进行管理
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:
db.ini
deploy_key_rsa
.gitignore文件也可以交给git管理
如果git add
无法添加某个文件到暂存区,可能是这个文件被.gitignore忽略了,如果你确实想添加该文件,可以使用-f强制添加
如果你觉得不应该忽略该文件,是.gitignore文件写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore -v App.class
检查是文件中哪行导致了App.class文件被git忽略
配置git
初始化本地仓库
将当前项目初始化为本地仓库后,项目中新建文件时会提示是否进行git add
操作,项目中,执行了git add
后的文件名是绿色,未执行git add
操作的文件名是红色,git commit
后文件名变为白色
可以手动add
、commit
文件和目录
git边栏中,console标签就是之前git命令执行的日志、log就是git log的内容
当在文件中编写新代码时,和本地库代码不一致的位置,前面会出现绿条
可以在源码上或提交时查看与本地库代码内容对比
由于本地库和远程库之间,各自记录的起点终点完全不同,因此git pull
或通过idea直接拉取代码会失败,所以先手工建立关联,使用--allow-unrelated-histories
参数,表示"允许忽略不相关的历史信息"地拉取
#拉取远程库数据
git pull [email protected]:handidiao/git-tutorial.git master --allow-unrelated-histories
#add commit拉取过来的数据
#将本地数据推送到远程库
git push -u [email protected]:handidiao/git-tutorial.git master -f
通过idea,add、commit后,就可以推送项目到远程仓库了
也可以commit的同时,push到远程仓库
当push到远程库时,如果有冲突,会提示如下信息,此时点击merge
此时提示如下信息,提示可以选择用自己的或者用远程库中内容,又或者进行合并,此处选择Merge
左侧为你的代码,中间为你修改之前代码,右侧为远程库中代码,此时可以将中间部分代码修改为你最后需要的代码,点击apply即可,此时本地库和工作空间代码已经被修改为最新,再次通过idea进行push即可最终解决冲突
通过克隆远程仓库方式创建项目