作为一个工作两年的开发同学,git是每天都要接触的工具。但IDEA对git的封装已经满足了日常的代码提交需求,所以一直是以点点点的形式进行代码提交与更新,几乎没用命令行提交过(现在想来也是有些惭愧),对于git架构与底层也了解甚少。近期刚好研究代码相关,就趁此机会把git完整的学习一下。
git的本质是版本控制系统。版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制系统主要分为集中式、分布式,分别以svn、git为代表。
CVCS
有一个集中管理的服务器用来保存所有的修订版本,开发同学们通过客户端连接到服务器,获取最新的文件或更新文件。从图例中就可以看出CVCS的特点:单点、网络强依赖。
常见的subversion,现归属Apache,是代表性的集中式版本控制系统,除此之外还有TortoiseSVN。通常都是可爱的小乌龟图案。
DVCS
不再使用中央仓库, 取而代之的是本地仓库与远端仓库。本地仓库里包含了所有的版本历史,与本地仓库交互并不需要网络。
Git
大部分版本控制系统存储的是每个文件与初始版本的差异。但git与常见的版本控制系统并不同。git以快照的形式来进行不同版本的保存。提交更新或保存项目状态时,对当时的全部文件创建一个快照并保存这个快照的索引。如果文件没有修改只保留一个链接指向之前存储的文件。常见的有gitlab、github。
集中式与分布式版本控制系统的最大区别在于,版本控制的位置在中央服务器还是本地电脑。
| 集中式 | 分布式 | |
| 服务器故障时是否可提交 | ❌ | ✅ |
| 无网络也可工作 | ❌ | ✅ |
分支(Branch):一条独立的开发线,与与开发主线分离,可在不影响主线的同时工作。
工作区(Workspace):本地的代码区。
暂存区(Staging Area):临时存放代码的改动,即文件.git/index。
本地git仓库(Local Repository):存储于本地,含有所有版本的项目数据。
远程git仓库(Remote Repository):存储于远端,含有所有版本的项目数据。
git 更像是一个小型的文件系统,提供了许多以此为基础构建的超强工具,而不只是一个简单的 VCS。
如果是研发人员,对git的提交绝对不陌生。在日常中使用git最高频的操作是将自己最新的修改推到远端分支,具体的操作流程如下:
git主要两大使用方式:图形化页面、命令行。
在许多ide中都可以通过点击页面菜单的方式进行git commit、push等操作。如下图就是IDEA中的git操作菜单,可以看到已支持的命令可覆盖大部分的日常git使用需求,但依旧无法支持全部git指令。使用起来较为简便,只需要点点点即可。
在Terminal中直接手敲命令完成git交互。可执行全部git指令,根据所需自定义参数等。需要手动输入命令,但灵活性较高。
总结了日常使用中最常用的六条命令如下。文章末尾也总结了git的大部分命令列表。
| git add | 增加git对指定文件的跟踪,将文件增加到暂存区 |
| git pull | 将远程仓库的代码拉到本地 |
| git push | 将代码从本地仓库上传到远程仓库 |
| git clone | 将一个远程仓库中的项目拷贝到本地 |
| git commit | 将所选暂存区的文件提交到本地仓库 |
| git checkout | 切换分支 |
一个文件在本地的状态变化主要有未跟踪、未修改、已修改、已暂存四种,会根据用户的操作不断变化。

在项目中有些文件无需纳入git管理,比如运行过程数据等。可记录在项目根目录的.gitignore中,去除git对该文件的管理。
GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表,详见https://github.com/github/gitignore
git支持打标签的方式来记录关键节点,可用于记录发布版本等。可以通过在特定的标签上创建一个新分支来复现打了标签的版本。
轻量标签(lightweight):一个特定提交的引用。
附注标签(annotated):存储在 Git 数据库中的一个完整对象。通常创建的标签都是附注标签。
| 标签列表 | git tag | 列出已有的标签 |
| git show ${标签名} | 某个标签信息与对应的提交信息 | |
| 创建标签 | git tag -a ${标签名} -m ${备注} | 创建附注标签 |
| git tag ${标签名} | 创建轻量标签 | |
| git tag -a ${标签名} ${某个提交的校验和} | 基于已有的提交创建标签 | |
| git push origin ${标签名} | 将标签推到服务器上 | |
| 恢复标签 | git checkout -b ${分支名} ${标签名} | 标签代码的恢复依赖于分支 |
几乎所有的版本控制系统都以某种形式支持分支。分支可以把个人的开发工作从主线上分离,以免影响开发主线。 在很多版本控制系统中,这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。git 的分支,其实本质上仅仅是指向提交对象的可变指针。做些修改后再次提交,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针。
| master | 主分支,代码的正式版本。原则上不能直接在master分支上修改,只能从其他分支合并。 其实master与其他分支并无不同,之所以用master做主分支,是因为git init默认创建的分支就是master,大家懒得改。 |
| develop | 主开发分支,包含要发到下一个release分支的代码。 |
| feature | 功能分支,主要用于开发新功能的分支。aone上新建变更后拉出的就是feature分支 |
| release | 预发布分支,在发布正式版本前,将待发布的分支都合并到release分支,打出一个预期发布版本。Aone上多分支发布的集成分支就是release分支。 |
| hotfix | bug修复分支,做短小精悍的bug修复。 |
| git branch | 创建新分支 ,相当于在当前所在的commit 上创建一个指针。Git 的分支实质上仅是包含所指对象校验和的文件,所以它的创建和销毁都异常高效。 |
| git checkout | 切换分支 |
概念
HEAD指针总是通过分支指针,间接的指向当前分支的最新提交。
样例
文字可能不好理解,我们直接看git中的head指向就明白了。在命令行中进入某个项目的文件夹,目前处于master分支。进入.git文件夹,里面包含一个HEAD文件。

查看head文件内容,发现指向另一个文件 refs/heads/master

那么我们继续查看这个文件,发现是一串commit id

head所指向的commit id就是master最新一次提交的commit id
blob:提交的文件,一个文件的一个版本对应一个blob对象
tree:目录,一个tree对象内部聚合了另一些tree或者blob
commit:一次提交.一个commit可以理解为某一个版本下的仓库的各个文件以及文件夹的快照。相当于聚合了这个版本下的blob以及tree对象。commit同时也会包含提交信息以及parent的commit。
在clone项目时,有两种方式:SSH、HTTPS。
安全性较高,需要生成SSH密钥,并将本地公钥上传至gitlab。
安全性较弱,使用用户名与密码登录。
可以对一些常用指令设置别名,减少每次的打字数
比如git commit,我想自定义成git ci,可设置git别名
git config --global alias.ci commit
后续commit只需要输入git ci即可。
这可以说是一个很有趣的话题了,作为一个"交友网站",读法还是十分多样的,大概如下:
具体怎么读,并没有标准答案,目前博主读的是[git],参照Linus的读法。原视频
| 常用指令 | |
| git clone | 将一个远程仓库中的项目拷贝到本地 |
| git add | 增加git对指定文件的跟踪,将文件增加到暂存区 |
| git commit | 将所选暂存区的文件提交到本地仓库 |
| git push | 将代码从本地仓库上传到远程仓库 |
| git pull | 将远程仓库的代码拉到本地 |
| git checkout | 切换分支 |
| 分支 | |
| git branch | 创建新分支 |
| git log | 按提交时间列出分支上的所有的更新 |
| git reset | 撤销操作,将head回退至指定状态 |
| git merge | 分支合并 |
| git diff | 工作目录中当前文件和暂存区域快照之间的差异 |
| 标签 | |
| git tag | 列出已有的标签 |
| git show ${标签名} | 某个标签信息与对应的提交信息 |
| git tag -a ${标签名} -m ${备注} | 创建附注标签 |
| git tag ${标签名} | 创建轻量标签 |
| git tag -a ${标签名} ${校验和} | 基于已有的提交创建标签 |
| git push origin ${标签名} | 将标签推到服务器上 |
| git checkout -b ${分支} ${标签} | 将标签记录的阶段代码恢复到分支上 |
| 仓库 | |
| git init | 初始化仓库 |
| git config --list | 列出所有 Git 当时能找到的配置。 |
| git status | 查看文件所处状态 |
| git ls-remote (remote) | 远程引用的完整列表 |
| git fetch | 拉取最新的远程仓库分支,本地仓库不变 |
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g
关于如何使用git设置类似Dropbox的服务,您有什么建议吗?您认为git是解决此问题的合适工具吗?我在考虑使用git+rush解决方案,你觉得怎么样? 最佳答案 检查这个开源项目:https://github.com/hbons/SparkleShare来自项目的自述文件:Howdoesitwork?SparkleSharecreatesaspecialfolderonyourcomputer.Youcanaddremotelyhostedfolders(or"projects")tothisfolder.Theseprojec
我编写了一个非常简单的“部署”脚本,作为我的裸git存储库中的post-updateHook运行。变量如下livedomain=~/mydomain.comstagingdomain=~/stage.mydomain.comgitrepolocation=~/git.mydomain.com/thisrepo.git(bare)core=~/git.mydomain.com/thisrepo.gitcore==addedremoteintoeachlive&stagegitslive和stage都初始化了gitrepos(非裸),我已经将我的裸仓库作为远程添加到它们中的每一个(名为co
我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://
Activeadmingem已添加到我的rails项目中,但每次我尝试安装railsgactive_admin:install时,我都会收到类似的错误git://github.com/activeadmin/activeadmin.git(atmaster)isnotyetcheckedout.Runbundleinstallfirst.我肯定在运行“railsgactive_admin:install”之前运行了bundle。运行“bundleshow”后,我看到我已将“*activeadmin(1.0.0.pre3f916d6)”添加到我的项目中,但不断收到此错误消息。我的gem文
我在bitbucket上创建了一个私有(private)git存储库并提交了代码。现在我想导出所有(提交、代码、历史记录)并将其导入github上的gitrepo。有没有办法做到这一点?谢谢 最佳答案 在本地检查所有内容到您的计算机和gitpull。创建一个github存储库将此存储库添加为您的第二个远程(“使用gitremote添加githubURL”)推送到第二个Remote 关于ruby-git:从bitbucket导出并导入github(带提交),我们在StackOverflow
亲测可用。Anerroroccurredwhileresolvingpackages:Projecthasinvaliddependencies: com.unity.xxx:No'git'executablewasfound.PleaseinstallGitonyour systemthenrestartUnityandUnityHub在我们使用PackageManager时,Unity允许我们使用Git上的package(点击加号,选择addpackagefromgitURL,或者是直接在Asset/Packages/manifest.json中添加包名)。但是这种操作需要我们事先装好g
目录一、什么是Websocket二、WebSocket部分header介绍三、HTTPVSWebSocket四、什么时候使用WebSockets五、关于SockJS和STOMP一、什么是Websocket根据RFC6455标准,Websocket协议提供了一种标准化的方式在客户端和服务端之间通过TCP连接建立全双工、双向通信渠道。它是一种不同于HTTP的TCP协议,但是被设计为在HTTP基础上运行。Websocket交互始于HTTP请求,该请求会通过HTTPUpgrade请求头去升级请求,进而切换到Websocket协议。请求报文如下:GET/spring-websocket-portfoli
我在Windows上使用GitBash来完成我的大部分Rails工作,每次我运行bundleexecrspecspec它都会提醒我“你必须geminstallwin32console才能使用Windows上的颜色”,然后以纯黑色和白色运行RSpec。但是我确实安装了win32console,当我在列表中运行gemlist时,它有win32console(1.3.0x86-mingw32)。RSpec工作正常,但我希望它有一些颜色。我用谷歌搜索了这个并找到了多种解决方案,但似乎没有一个适合我。有人可以写出在GitBashforWindows上使用RSpec获取颜色的“循序渐进”方法吗?
我想实现一个Rake任务,自动执行一些我必须完成的任务,以便将我的更改从开发转移到生产(是的,我知道有像Capistrano这样的东西,它对我来说太多了).中间是gitadd-i等一些交互命令,以及一系列commit和push。在生产方面,将有pull和Assets任务要做。一直输入相同的命令很乏味,所以我想完全自动化。我还没有找到Git的RubyAPI。它应该在Windows7下工作,并且至少允许以下命令:gitadd、gitstatus、gitcommit、gitpush,gitpull. 最佳答案 我知道,坏习惯,但我想记录一