使用git也有好久了,后来有一段时间一直没有机会去使用,如今想来总结一下本身学习了这么长时间的一些心得感悟,我写的博客通常都是开了一个轮廓和框架,等到之后有所思有所悟了还会增长的,正如软件同样一直都会不断地更新,加入新的东西,修改一些过期的东西,咱们作人和作事也应该这样,不断地学习新的知识,取其精华去其糟粕,不断地进步和增加。关于git也是用来进行项目管理的,一样是为了团队协做,这个场景使你们使用着各自的电脑,可能相隔万里,只要可以进行通讯,就可以从github上进行代码的同步操做,这是很是有意思的。git
相比于之前的subversion等项目管理软件,git更加的强大,而且很好用,这里的好用有两种意思,第一是功能很强大,每个成员均可能将中心仓库的代码给删除了,固然也能植入本身的内容,第二个好用是一不当心提交了错误的代码一样的也会被其余成员所使用,形成很恶劣的影响。所以十分熟悉git的操做,明白背后的意义,以及合理的使用git来进行代码的维护是很是重要的。上次咱们学习了maven是为了管理依赖,统一风格,而git则是为了同步代码,管理项目的进程,这二者一个面向于代码的同步和转移,另外一个面向于项目内部的实现和依赖的处理,二者结合起来组成的开发能力就很是的强大了,对于团队开发来讲很是的重要,是两把利剑。github
众所周知,Git是一个软件,安装在本地的机器上,用来从Github这个远程仓库中pull、push代码,从而达成团队协做开发的目的。这二者就比如是抽水机和池塘,Git从GitHub之中获得代码而且维护着版本和分支的信息,从而进行合并和开发。所以使用Git必需要有Github帐号以及项目才行。shell
Git的安装很是简单,只须要从官网上下载并安装就能够了,不用配置什么环境变量就可以进行使用了。一样的官网上还提供了不少的GUI用来对Git得到的代码进行分析和操做,咱们能够大体了解一下。安装的过程很简单,咱们再也不赘述,安装完成以后就能打开使用了。能够看到这个shell使用的是Linux中的命令,很是的有意思。数据库
接下来咱们在github上建立一个项目,放一些文件进去便于咱们的实验。考虑到多人协做的问题,咱们先建立一个组织,在组织下面在建立项目,同时能够邀请其余人加入咱们的项目实现协同工做。数据结构
这样咱们的项目就建好了,剩下的就是邀请其余人进入其中,而且最好的就是将别人的公钥放入本身的Github上去,这样其余人在使用Git的时候就不用每次都输入帐户和密码了。在设置,SSH或者GPG秘钥之中,咱们加入本身和别人的公钥。可是须要注意的一点就是,咱们若是使用SSH加密的话,须要将项目改为使用SSH可以获取的,以后咱们在添加SSH秘钥,这一点很是重要!!!!!!app
在Git中使用以下命令来生成秘钥和公钥:框架
ssh-keygen -t rsa -C 邮箱号
而后咱们转到生成的公钥和私钥的目录,私钥是咱们本身的打死都不能给别人,而公钥就是让别人拿来给本身进行通讯的,所以,咱们把公钥发给这个项目的管理员,让他在刚刚的地方复制进去咱们的公钥,这样就能很好的工做了。eclipse
咱们能够根据Git项目的网址将项目clone到本地,这个不须要秘钥,可是若是之后提交内容的时候就须要了:ssh
好比咱们在这个时候不加入公钥到仓库之中,那么咱们操做到了git push的时候就不能向下执行了,很是的麻烦,须要输入帐号和密码,而且以后仍是须要配置的。maven
那么咱们将公钥加入仓库之中,此时管理员会收到邮件提醒,作的仍是很到位的:
而后咱们再从新下载一下项目,能够看到项目加载成功!
对于clone下来的项目,开发就是按照以往的开发方法,将这些文件导入到myeclipse之中,可能使用了maven,那就更新依赖,以后就能够进行开发了,那么什么叫作开发呢?!开发的本质其实就是增长文件、修改已有的文件、删除某些文件,再说白一点就是对原来的文件库进行增删改操做,这就是开发,那么由于这些操做必然会影响到咱们的本地仓库之中的代码,好比咱们增长了一个文件,又修改了一个文件,还删除了一个文件,而后要怎么样同步到远程仓库之中呢,那就须要用到Git的强大功能了,另外提醒一点,在咱们使用git的时候必定要把myeclipse关闭了,否则由于其中某些文件没保存,或者产生了一些临时文件被咱们提交了就可能形成错误。
下面咱们模仿开发以后提交的过程:
首先,当咱们clone下来文件以后,第一件事是什么呢?!绝对不是直接就开发了,而是将Git切换到这个目录内部,而后新建一个分支,在新的分支上进行改动,这一点是重中之重,能够防止咱们将原来的文件给修改了以后恢复不了的问题。在咱们的项目中默认只有一个主分支master,咱们在任什么时候间不能在这个分支上进行任何的开发。
git checkout -b 分支名
这样咱们进行的开发都是在这个新的分支上开发了,不会影响主分支的结果,好比咱们在新的分支上放入一个文件。
若是直接切换到主分支,此时由于没有保存这个改变,咱们在主分支也能看到这个文件了,这是由于咱们在没有保存这些改变到新分支上面的时候,这些文件只能算是文件系统上面的文件天然能被全部分支看见,其实对分支内部的数据结构来讲是透明的。
可是咱们接下来在切换回新分支,而后保存以后在切换回主分支看看,这样也解决了咱们的一个疑惑,若是随便扔到分支里面一个文件就要认可的话,那么使用起来也太须要当心了。
上面咱们使用了:
git add . git commit -m "描述信息"
接下来咱们正式将开发好的新分支合并到主分支上面:
git checkout master git pull git checkout "新分支" git rebase -i master git checkout master git merge "新分支"
zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (zyr_first) $ git checkout master Switched to branch 'master' Your branch is up to date with 'origin/master'. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git pull Already up to date. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git checkout zyr_first Switched to branch 'zyr_first' zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (zyr_first) $ git rebase -i master Successfully rebased and updated refs/heads/zyr_first. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (zyr_first) $ git checkout master Switched to branch 'master' Your branch is up to date with 'origin/master'. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git merge zyr_first Updating 4b1509b..313111a Fast-forward test1.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test1.txt zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git push Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 331 bytes | 331.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:zyrtest/GitTest.git 4b1509b..313111a master -> master zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $
咱们能够看到新的改动已经成功的提交了。
咱们整理一下思路,首先新建一个分支(checkout -b),而后在新分支上面开发,以后将开发的内容绑定到新分支(add,commit),而后切换回主分支,使用pull命令将最新版本的项目再次下载下来,这一点是很是重要的,若是没有这一步,其余人可能在咱们下载、修改、到提交的这么长的时间段已经将新的内容提交上去了,若是咱们直接将好久之前咱们下载的东西和咱们本身修改的东西结合到一块儿提交的话使用push命令,可能形成不可挽回的结果,那就是其余人在这个时间段提交的东西所有都没有了,很容易被炒鱿鱼的~~~而后咱们再次切换回新分支,让新分支挂载到master的基线上面(rebase),以后咱们再次切换回master,而后进行最终的合并,merge,最后咱们提交,其实这个时候咱们也是有必定风险的,假设在咱们push的同时,其余人也在push,这个几率过小了,可是也有可能发生的,若是是这样,总有一我的的会被刷掉,这样某一方就须要从新下载最新的,合并以后而后提交了,可是开发团队人比较少,这种几率小得几乎不用考虑。
下面咱们总结一下整个流程,在这里我使用操做来表达:
最后一步,很是重要,不能忘记!
这就是使用Git进行项目开发的几个过程,须要注意:只有在提交的时候才能在master目录,其他的状况下都要在本身建立的分支中。
固然还有一些基本的设置:
git config --global user.email "邮件名称" git config --global user.name "用户名"
基本的查看命令:
git branch -a #查看全部分支 git remote -v #查看远程仓库
git status #查看分支提交状态
git checkout #查看当前分支
一样的还能使用别名:这样能够少写不少东西,很是的方便。
git config --global alias.st status git config --global alias.co checkout git config --global alias.ci commit git config --global alias.br branch 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"
.gitignore文件
有些时候,咱们必须把某些文件放到Git工做目录中,但又不能提交它们,好比保存了数据库密码的配置文件等等,这个问题解决起来也很简单,在Git工做区的根目录下建立一个特殊的.gitignore文件,而后把要忽略的文件名填进去,Git就会自动忽略这些文件。
忽略某些文件时,须要编写.gitignore;网上已经有针对不一样语言的ignore内容了,所以,咱们只用再加上本身的一些须要忽略的文件就能够了。
.gitignore文件自己要放到版本库里,而且能够对.gitignore作版本管理!
忽略文件的原则是:
一、忽略操做系统自动生成的文件,好比缩略图等;
二、忽略编译生成的中间文件、可执行文件等,也就是若是一个文件是经过另外一个文件自动生成的,那自动生成的文件就不必放进版本库,好比Java编译产生的.class文件;
三、忽略带有敏感信息的配置文件,好比存放口令的配置文件。
忽略特定文件:.gitignore文件
git check-ignore -v 文件名
# 若是发现多是写得有问题,须要找出来到底哪一个规则写错了,能够用命令检查.gitignoregit check-ignore
咱们新建一个文件叫作“.gitignore”,在文件里写上咱们不想提交可是又必须使用的那个文件,好比这里我再建立一个文件:
而后咱们使用git status看一下,以后咱们发现发生改变的只有.gitignore,而没有了咱们想要忽略的文件,这样就等因而自动过滤掉了这个文件,而后咱们将发生改变的.gitignore文件上传便可。
在这里我直接在主分支上修改了,是一个很差的习惯,你们必定要新建一个分支再修改,否则可能会出现错误。
同时咱们也能查看是否将咱们的某些文件放到.gitignore里面了:
查看不一样: git diff # 查看工做区与仓库的不一样 git diff HEAD # 查看工做区与当前分支最新commit之间的差别 git diff <file> # 查看当前文件与仓库文件的不一样 git diff <commit_1>...<commit_2> # 查看两次提交之间的差别 查看历史记录: git log -3 # 显示过去3次提交 git log --pretty=oneline # 只显示commit_id和提交注释 git log --graph # 显示为分支合并图 git log --abbrev-commit # 显示缩略commit_id git log --stat # 显示每次commit发生变动的文件 git log -S <keyword> # 根据关键词搜索提交历史 git log --follow <file> # 显示文件的版本历史,同 git whatchanged <file> git log -p <file> # 详细列出与文件相关的每一次diff git reflog #查看每一次命令和操做
跳转至指定版本(commit) HEAD 当前版本号,HEAD^ 上一个版本号,HEAD^^ 上上个版本号,HEAD~100 上一百个版本号 git reset --hard <commit_id>
撤销修改: git checkout [<commit_id|branch|tag>] [--] <file> # 恢复版本库的指定版本到工做区,省略commit_id则从暂存区进行恢复, #--用于避免commit_id|branch|tag与file重名 git reset HEAD <file> # 撤销暂存区的修改
删除文件: git rm <file> # 删除工做区文件,并将此次删除放入暂存区 git commit -m "delete an exist file" git rm --cached <file> # 中止追踪指定文件,保留在工做区
文件更名: git mv <oldname> <newname> # 更名文件,并将此次更名放入暂存区 git commit -m "rename an file oldname to newname"
显示指定版本(commit):
git show <commit_id> git show --name-only <commit_id> # 显示某次提交发生变化的文件 git show <commit_id>:<file> # 显示某次提交时,某个文件的内容
一、关联本地库与远程库,origin为该远程库在本地的名称 git remote add origin git@XXX.git git remote add origin https://github.com/XXX.git 2.将本地库的内容推送到远程库 git push [-u] [--all] [--force] origin <local_b>:<remote_b> # 将本地local_b分支的更新推送到远程库origin的remote_b分支, # (-u)表示把二者关联起来,同时指定origin为默认主机, # (--all)表示推送本地全部分支, # (--force)表示强行推送,即便有冲突 git push origin <local_b> # 将本地local_b分支的更新推送到远程库origin的相同名称分支,若是后者不存在则会被建立 git push origin :<remote_b> # 推送一个空的本地分支到远程分支,等于删除指定的远程分支 git push origin # 将本地当前分支的更新推送到远程库origin中有追踪关系的远程分支 git push # 适用于当前分支只有一个追踪分支的状况,或指定默认主机的状况 git push origin <tag_name> # 推送一个本地标签到远程库 git push origin --tags # 推送所有未推送过的本地标签 git push origin :refs/tags/<tag_name> # 删除一个远程标签 3.克隆远程库到本地库,自动关联,且远程库的默认名称为origin git clone git@XXX.git git clone [-o origin] <addr> [local_dir_name] # 指定远程库名称和本地目录名称 4.查看远程库 git remote git remote -v # 显示远程库的地址,包括fetch和push地址 git remote show origin # 显示远程库的详细信息 git remote add origin git@XXX.git # 添加远程库 5.获取远程库 git fetch # 更新全部远程库所包含分支的最新commit_id,并记录到.git/FETCH_HEAD文件中 git fetch origin # 更新远程库origin的全部分支的最新commit git fetch origin <remote_b> # 更新远程库origin的remote_b分支 git fetch origin <remote_b>:<local_b> # 更新远程库origin的remote_b分支,并在本地建立local_b分支保存远程分支的数据 git pull [--rebase] origin <remote_b>:<local_b> # 获取远程库origin的remote_b分支的更新,而后与本地local_b分支合并 git pull origin <remote_b> # 获取远程库origin的remote_b分支的更新,而后与本地当前分支合并 git pull origin # 获取远程库origin中与本地当前分支有追踪关系的远程分支的更新,而后合并 git pull # 适用于当前分支只有一个追踪分支的状况 6.创建关联/追踪关系tracking git branch --set-upstream <local_b> origin/<remote_b> # 指定local_b分支追踪origin/remote_b分支
分支: 1.建立分支 git branch <branch_name> [<start_point>] # 当指定start_point时,即为当前分支的某一次commit来建立分支 2.切换分支 git checkout <branch_name> git checkout <commit_id> # 切换到某个commit,进入detached HEAD状态 3.建立并切换分支 git checkout -b <branch_name> [<start_point>] # 等价于前两步操做 4.查看分支 git branch # 查看本地分支,当前分支前面会标一个*号 git branch -r # 查看远程分支 git branch -a # 查看全部分支 5.合并分支,合并模式:Fast-forward快进模式,优先使用,但删除分支会丢失分支信息 git merge <branch_name> # 合并指定分支到当前分支 git merge --no-ff -m "merge with a new commit" <branch_name> # 强制禁用ff模式,merge时会生成一个新的commit git rebase [-i] <branch_name> # 将当前分支的commit取消掉,并临时保存为补丁, #而后把当前分支更新为指定分支,最后把保存的补丁应用到该分支上,(-i)打开交互模式 git rebase --continue # 当有冲突并解决完成时,使用git-add命令更新,而后执行命令继续应用余下的补丁 git rebase --abort # 中断合并并恢复 6.删除分支 git branch -d <branch_name> git branch -D <branch_name> # 强行删除一个未合并的分支 git branch -dr origin/<remote_b> # 删除一个远程分支 7.隐藏当前工做区的修改,便于建立bug分支 git stash # 隐藏 ...debug... git stash list # 查看隐藏内容列表 git stash apply [stash@{i}] # 恢复指定隐藏内容 git stash drop [stash@{i}] # 删除指定隐藏内容 git stash pop [stash@{i}] # 恢复并删除指定隐藏内容
这里说一下stash,暂存工做区。咱们在已有的分支中,修改一个文件的部份内容,注意是修改,不是建立新的文件。若是咱们此时还没完成这个分支的工做,可是必须跳到其余分支去处理任务,咱们使用git stash暂存当前的修改,能够看到工做树又干净了,之前的修改不见了,又恢复到了没修改以前的状态,而后咱们跳到新的分支去继续修改其余的任务,当修改完毕以后,在新的分支上可能有保存和提交,以及最终push,而后咱们回到本分支,使用git stash pop命令就能够恢复到以前的状态了,而后继续修改,最终提交便可。
标签做用: 在开发的一些关键时期,使用标签来记录这些关键时刻, 例如发布版本, 有重大修改, 升级的时候, 会使用标签记录这些时刻, 来永久标记项目中的关键历史时刻;
标签 1.建立标签 git tag <tag_name> # 给当前分支的最新commit(即HEAD)建立标签 git tag <tag_name> <commit_id/abbrev_commit_id> # 给指定commit 建立标签 git tag -a <tag_name> -m "create a new tag on a commit" <commit_id/abbrev_commit_id> # 建立带有说明的标签 git tag -s <tag_name> -m "create a new tag on a commit" <commit_id/abbrev_commit_id> # 用PGP签名标签 2.查看标签 git tag git show <tag_name> # 查看指定标签 3.删除标签 git tag -d <tag_name>
git有不少操做,真正使用的其实也就那几个,可是有的时候咱们的项目很是复杂,须要不少其它的功能的时候,这些看似不重要的功能就有用了,在学习的时候咱们实用便可,不须要掌握全部的操做,可是要可以稍微了解一下这些功能,在遇到复杂问题时可以去很好的解决,关于Git的说明就到这里,基本上可以知足咱们开发的须要。
参考文献:https://blog.csdn.net/q449560173/article/details/65628261