好的,在看到this post by PJ Hyett之后,我决定跳到最后并使用Git。
所以我需要的是初学者对Git的实用指南。 “初学者”被定义为知道如何处理他们的编译器的人,在某种程度上理解Makefile是什么,并触及源代码控制而不理解它。
“实用”被定义为这个人不想详细了解Git在后台做什么,甚至不关心(或知道)它是分布式的。您的回答可能暗示了可能性,但尝试瞄准想要在备份和安全的“服务器”上保留“主”存储库的初学者,并将其本地存储库视为仅仅是“客户端”资源。 / p>
所以:
我会不时地查看这些条目并“整理”它们以便它们具有一致的外观/感觉并且可以轻松扫描列表 - 随意按照简单的“标题 - 简要说明 - 说明列表 - 陷阱和额外信息“模板。我还将链接到上面的项目符号列表中的条目,以便以后轻松找到它们。
答案 0 :(得分:118)
git存储库只是一个包含特殊.git
目录的目录。
这与“集中式”版本控制系统(如subversion)不同,其中“存储库”托管在远程服务器上,您将checkout
置于“工作副本”目录中。使用git,您的工作副本是存储库。
只需在包含您要跟踪的文件的目录中运行git init
。
例如,
cd ~/code/project001/
git init
这会在当前目录中创建一个.git
(隐藏)文件夹。
要创建一个新项目,请使用附加参数(要创建的目录的名称)运行git init
:
git init project002
(This is equivalent to: mkdir project002 && cd project002 && git init)
要检查当前当前路径是否在git存储库中,只需运行git status
- 如果它不是存储库,它将报告“致命:不是git存储库”
您还可以列出.git
目录,并检查它包含类似于以下内容的文件/目录:
$ ls .git
HEAD config hooks/ objects/
branches/ description info/ refs/
如果出于某种原因你希望“去git”一个存储库(你希望停止使用git来跟踪该项目)。只需删除存储库基础级别的.git
目录即可。
cd ~/code/project001/
rm -rf .git/
警告:这会破坏所有修订历史记录,所有您的代码, git所做的一切。它不会触及“当前”文件(您当前可以看到的文件),但以前的更改,删除的文件等将无法恢复!
答案 1 :(得分:110)
答案 2 :(得分:59)
嗯,尽管你要求我们“简单地”链接到其他资源,但是当已经存在一个真正相当不错的社区成长(和不断增长的)资源时,这是非常愚蠢的:Git Community Book。说真的,一个问题中的这20多个问题将是简洁和一致的。 Git社区手册以HTML和PDF格式提供,可以通过清晰,格式良好和经过同行评审的答案回答您的许多问题,并且格式允许您直接跳到手头的问题。
唉,如果我的帖子真的让你心烦意乱,那么我会删除它。就这么说吧。
答案 3 :(得分:56)
让git忽略你不希望它跟踪的文件的能力是非常有用的。
要忽略您提供模式的文件或文件集。 git的模式语法相当简单,但功能强大。它适用于我将提到的所有三个不同的文件。
来自gitignore(5)手册页的精彩示例:
$ git status
[...]
# Untracked files:
[...]
# Documentation/foo.html
# Documentation/gitignore.html
# file.o
# lib.a
# src/internal.o
[...]
$ cat .git/info/exclude
# ignore objects and archives, anywhere in the tree.
*.[oa]
$ cat Documentation/.gitignore
# ignore generated html files,
*.html
# except foo.html which is maintained by hand
!foo.html
$ git status
[...]
# Untracked files:
[...]
# Documentation/foo.html
[...]
通常有三种不同的方法可以忽略未跟踪的文件。
1)忽略存储库的所有用户:
将名为 .gitignore 的文件添加到工作副本的根目录。
修改 .gitignore 以符合您/不应忽略哪些文件的偏好。
git add .gitignore
并在完成后提交。
2)仅忽略您的存储库副本:
使用您的首选模式在工作副本中添加/编辑文件 $ GIT_DIR / info / exclude 。
Ex:我的工作副本是〜/ src / project1所以我要编辑〜/ src / project1 / .git / info / exclude
你已经完成了!
3)在所有情况下,忽略您的系统:
系统的全局忽略模式可以放在一个名为您希望的文件中。
我个人称之为〜/ .gitglobalignore然后我可以通过使用以下行编辑〜/ .gitconfig 文件让git知道这个文件:
core.excludesfile = ~/.gitglobalignore
你已经完成了!
我发现gitignore手册页是获取更多信息的最佳资源。
答案 4 :(得分:47)
如何“标记”或“释放”特定文件集的特定修订集,以便您以后可以随时提取该文件?
使用git tag
命令。
要简单地“标记”当前版本,您只需运行..
git tag -a thetagname
git tag -a 0.1
git tag -a 2.6.1-rc1 -m 'Released on 01/02/03'
要列出当前代码,只需运行没有参数的git tag
或-l
(小写L):
$ git tag -a thetagname # and enter a message, or use -m 'My tag annotation'
$ git tag -l
thetagname
要删除标记,请使用-d
标记:
$ git tag -d thetagname
Deleted tag 'thetagname'
$ git tag
[no output]
要标记特定(上一个)提交,您只需执行..
git tag [tag name] [revision SHA1 hash]
例如:
git tag 1.1.1 81b15a68c6c3e71f72e766931df4e6499990385b
注意:默认情况下,git会创建一个“轻量级”标记(基本上是对特定修订的引用)。 “正确”的方式是使用-a
标志。这将启动您的编辑器,询问标记消息(与要求提交消息相同,您也可以使用-m
标志在命令行上提供标记消息)。使用带注释的标记创建一个具有自己的ID,日期,标记(作者)和可选的GPG签名(使用-s
标记)的对象。
有关详情,请参阅this post
git tag mytagwithmsg -a -m 'This is a tag, with message'
要列出带注释的标签,请使用-n1
标志显示每个标签消息的1行(-n245
以显示每个注释的前245行,依此类推):
$ git tag -l -n1
mytagwithmsg This is a tag, with message
有关详细信息,请参阅git-tag(1) Manual Page
答案 5 :(得分:46)
GIT的工作流程示例。
Git非常灵活,能够很好地适应任何工作流程,但不强制执行特定的工作流程可能会产生负面影响,使得很难理解除了线性“备份”工作流程之外使用git可以做些什么,以及分支如何有用例如。
这个blog post很好地解释了一个非常简单但有效的工作流程,使用git很容易设置。
引用博客文章: 我们认为origin / master是主要的分支,HEAD的源代码总是反映生产就绪状态:
工作流程已经变得非常流行,可以创建一个实现此工作流程的项目:git-flow
简单的工作流程的简单说明,您可以在开发中进行所有更改,并且只有在代码处于生产状态时才能掌握:
现在假设您要处理新功能或重构模块。你可以创建一个新的分支,我们可以称之为“功能”分支,这需要一些时间并且可能会破坏一些代码。一旦您的功能“足够稳定”并希望将其“更接近”生产,您就可以将功能分支合并到开发中。当合并后所有错误都被整理出来并且您的代码通过所有测试时,您可以将更改推送到主服务器中。
在此过程中,您会发现一个可怕的安全漏洞,必须立即修复。您可以拥有一个名为修补程序的分支,它可以使更改比正常的“开发”分支更快地恢复生产。
在这里,您可以看到此功能/修补程序/开发/制作工作流程的外观(在博客文章中有详细解释,我再说一遍,博客文章详细解释了整个过程,并且更好了比我做的。
答案 6 :(得分:39)
这是PJ Hyett的帖子的副本,因为它不再可用了:
Git并不难
2008年11月23日
当我们告诉人们为什么要这样做时 使用Git over Subversion,这是首选 线是,“Git做Subversion更好 比Subversion,但它做了很多 不止于此。“
“更多”由一堆组成 让Git真正闪耀的东西, 但它可能是非常压倒性的 那些来自其他SCM的人就像 颠覆。
那就是说,没有什么能阻止的 你就像使用Git一样 在你做的时候颠覆 过渡。
假设你已经安装了 必要的软件,并有一个遥控器 存储库某处,这就是你 会抓住代码并推动你的 改回Subversion:
$ svn checkout svn://foo.googlecode.com/svn/trunk foo
# make your changes
$ svn commit -m "my first commit"
你将如何在Git中做到这一点:
$ git clone git@github.com:pjhyett/foo.git
# make your changes
$ git commit -a -m "my first commit"
$ git push
让它成功的另一个命令 Git的。额外的命令很大 影响,但为了目的 这篇文章,这就是我们所说的 关于,一个额外的命令。
看,它确实不是那么难。
更新:我不得不提那相当于 在Subversion中更新本地副本 与Git相比,
svn update
和 分别为git pull
。只有一个 在这两种情况下命令。
答案 7 :(得分:33)
安装msysgit
有几个下载:
这也安装了一个Cygwin bash shell,所以你可以在一个更好的shell(比cmd.exe)中使用git
,还包括git-gui(可通过git gui
命令访问,或者Start > All Programs > Git
菜单)
使用git-osx-installer,或者也可以从源
安装使用本机包管理器安装git
。例如,在Debian(或Ubuntu)上:
apt-get install git-core
或者在Mac OS X上,通过MacPorts:
sudo port install git-core+bash_completion+doc
...或者fink:
fink install git
...或Homebrew:
brew install git
基于Red Hat的发行版,例如Fedora:
yum install git
在Cygwin中,Git包可以在“devel”部分找到
在Mac OS X中,如果安装了Developer Tools,则可以非常轻松地从源代码编译Git。从http://git-scm.com/下载最新版本的Git .tar.bz
或.tar.gz
,然后将其解压缩(在Finder中双击)
在Linux / BSD /等上。它应该是一样的。例如,在Debian(和Ubuntu)中,您需要通过build-essential
安装apt
包。
然后在终端中,cd
到解压缩文件的位置(运行cd ~/Downloads/git*/
应该有效),然后运行..
./configure && make && sudo make install
这会将Git安装到默认位置(/usr/local
- 所以git
将位于/usr/local/bin/git
)
它会提示您输入密码(对于sudo
),这样就可以写入/usr/local/
目录,只能由“root”用户访问,因此需要sudo !
如果您要将它安装在不同的地方(因此Git的文件不与其他工具混合使用),请使用--prefix
和configure命令:
./configure --prefix=/usr/local/gitpath
make
sudo make install
这会将git
二进制文件安装到/usr/local/bin/gitpath/bin/git
中 - 因此您不必每次都输入该二进制文件,您应该在$PATH
添加以下行添加到您的~/.profile
中export PATH="${PATH}:/usr/local/bin/gitpath/bin/"
:
--prefix=/Users/myusername/bin
如果您没有sudo访问权限,可以使用~/bin/
并安装到您的主目录中。请务必将$PATH
添加到~/work/track/git
脚本x-git-update-to-latest-version自动完成了很多这样的工作:
此脚本更新我的git repo的本地克隆(位于
/usr/local/git
的localy),然后配置,安装(git describe
-/usr/local/git
)并更新/usr/local/git/bin
符号链接。这样,我
PATH
可以MANPATH
,我总是使用最新版本。此脚本的最新版本还会安装手册页。您需要调整
/usr/local/git/share/man
以包含{{1}}目录。
答案 8 :(得分:32)
假设你做了一个拉,将它合并到你的代码中,并决定你不喜欢它。 使用git-log或tig,找到你想要回到的地方的哈希值(可能是你在拉/合并之前的最后一次提交)复制哈希,然后执行:
# Revert to a previous commit by hash:
git-reset --hard <hash>
您可以使用 HEAD ^ 作为上次提交的快捷方式,而不是哈希值。
# Revert to previous commit:
git-reset --hard HEAD^
答案 9 :(得分:31)
如何设置普通存储库[{3}} - 但是如何设置一个团队存储库,每个人都可以从中拉出和推送?
假设您的团队已经拥有可以使用的共享组成员资格。
mkdir /your/share/folder/project.git
cd /your/share/folder/project.git
newgrp yourteamgroup # if necessary
git init --bare --shared
要开始使用此存储库,最简单的方法是从您已经使用的本地存储库开始:
cd your/local/workspace/project
git remote add origin /your/share/folder/project.git
git push origin master
其他人现在可以克隆它并开始工作:
cd your/local/workspace
git clone /your/share/folder/project.git
在目标服务器上设置用户帐户。无论您使用没有密码的帐户,使用密码的帐户,还是使用authorized_keys
,都取决于您所需的安全级别。请查看here以获取更多信息。
如果所有开发人员使用同一帐户访问此共享存储库,则无需使用上述--shared
选项。
以与上面相同的方式启动存储库后,您可以像这样执行初始推送:
cd your/local/workspace/project
git remote add origin user@server:/path/to/project.git
git push origin master
看到与上面的相似之处?唯一可能发生的事情是,如果帐户有密码,SSH会要求输入密码。如果您在没有密码的帐户上收到此提示,则SSH服务器可能已禁用PermitEmptyPasswords
。
克隆现在看起来像这样:
cd your/local/workspace
git clone user@server:/path/to/project.git
答案 10 :(得分:28)
git status
是你的朋友,经常使用它。适合回答以下问题:
与svn status
不同,git status
即使在大型项目上也能立即运行。我经常发现它在学习git经常使用它时让人放心,以确保我所发生的事情的心智模型是准确的。现在我大多只是用它来提醒自己自从我上次提交以来我已经改变了什么。
显然,如果您的.gitignore配置得当,它会更有用。
答案 11 :(得分:27)
编辑完文件后,需要将更改提交给git。执行此命令时,它会询问提交消息 - 这只是一个简单的文本,告诉每个人你已经改变了什么。
$ git commit source/main.c
将文件main.c提交到./source /
目录中$ git commit -a # the -a flag pulls in all modified files
将提交所有已更改的文件(但不提交新文件,需要使用git-add将这些文件添加到索引中)。如果你只想提交某些文件,那么你需要先使用git-add暂存它们,然后在没有-a标志的情况下进行提交。
提交仅更改本地存储库,而不是远程存储库。如果要将提交发送到远程存储库,则需要进行推送。
$ git push <remote> <branch> # push new commits to the <branch> on the <remote> repository
对于来自CVS或SVN的人来说,这是一个变化,因为提交到中央存储库现在需要两个步骤。
答案 12 :(得分:27)
git存储库中的默认分支称为master
。
要创建新分支,请使用
git branch <branch-name>
查看当前存储库类型
中所有分支的列表git branch
如果您想切换到另一个分支,可以使用
git checkout <branch-name>
创建新分支并一步切换到
git checkout -b <branch-name>
要删除分支,请使用
git branch -d <branch-name>
要使用当前分支的更改创建分支,请执行
git stash
git stash branch <branch-name>
答案 13 :(得分:21)
$ git pull <remote> <branch> # fetches the code and merges it into
# your working directory
$ git fetch <remote> <branch> # fetches the code but does not merge
# it into your working directory
$ git pull --tag <remote> <branch> # same as above but fetch tags as well
$ git fetch --tag <remote> <branch> # you get the idea
这几乎涵盖了从远程存储库获取代码的最新副本的所有案例。
答案 14 :(得分:20)
Pro Git免费书绝对是我的最爱,特别是初学者。
答案 15 :(得分:18)
Git Magic就是你所需要的。保证或退款!
答案 16 :(得分:16)
如果要合并分支(例如master
到release
),请确保当前分支是您要合并的目标分支(使用git branch
或{ {1}}查看您当前的分支。)
然后使用
git status
(其中git merge master
是您要与当前分支合并的分支的名称)。
如果有任何冲突,您可以使用
master
查看您必须解决的待处理冲突。
答案 17 :(得分:16)
我还发现Git Internals非常有用。它由Scott Chacon(Pro Git的作者和Git Community Book的维护者)撰写。我喜欢Git Internals的是它focuses on the concepts first and then the commands,并且它是~100个小页面,它很容易消化。
答案 18 :(得分:13)
git log -- filename
答案 19 :(得分:12)
假设有一个远程存储库,您从中克隆了本地存储库,并且还假设该远程存储库上有一个名为“some_branch”的分支,以下是如何在本地跟踪它:
# list remote branches
git branch -r
# start tracking one remote branch
git branch --track some_branch origin/some_branch
# change to the branch locally
git checkout some_branch
# make changes and commit them locally
....
# push your changes to the remote repository:
git push
答案 20 :(得分:11)
了解Git如何运作的真正好文章是The Git Parable。非常推荐!
答案 21 :(得分:10)
比较命令为git diff
。
比较文件的2个修订版:
$ git diff <commit1> <commit2> <file_name>
将commit1与commit2区别开来;如果你改变了顺序,那么文件会反过来,这可能不是你期望的......
将当前暂存的文件与存储库进行比较:
$ git diff --staged <file_name>
将当前的非暂存文件与存储库进行比较:
$ git diff <file_name>
答案 22 :(得分:9)
为什么还有另一个方法?网上有很好的,比如git guide这是完美的开始。它有很好的链接,包括可以贡献的git book(托管在git hub上),这对于这个集体任务来说是完美的。
在stackoverflow上,我更愿意看到你最喜欢的技巧!
我最近才发现的是git stash
,解释here,这使您可以保存当前的工作并转到另一个分支
答案 23 :(得分:9)
apt-get install tig
在git repo中输入'tig',查看交互式日志,在任何日志上点击'enter'以查看有关它的更多信息。 h 寻求帮助,其中列出了基本功能。
“Tig”向后退是“Git”。
答案 24 :(得分:8)
假设您已经从某个远程存储库克隆了远程存储库。
# create a new branch locally
git branch name_of_branch
git checkout name_of_branch
# edit/add/remove files
# ...
# Commit your changes locally
git add fileName
git commit -m Message
# push changes and new branch to remote repository:
git push origin name_of_branch:name_of_branch
答案 25 :(得分:8)
我开始使用官方Git tutorial。我认为这对初学者来说已经足够实用了(按照你的定义,我是,现在仍然是初学者!我几乎没有掌握makefile,我只使用了Apache Subversion等等。)
答案 26 :(得分:8)
使用分支名称前面的:
执行遥控器推送
git push origin :mybranchname
origin
您的远程名称和mybranchname
即将删除的分支名称
答案 27 :(得分:7)
答案 28 :(得分:7)
首先转到空目录,使用“git init”将其作为存储库,然后将远程仓库克隆到您自己的目录中。
git clone user@host.com:/dir/to/repo
无论你最初克隆的地方是“git pull”默认拉出的地方。
答案 29 :(得分:7)
推送和拉动更改
以简化的方式,只需git push
和git pull
。合并更改,如果存在冲突,git会通知您,您可以手动解决。
当您第一次推送到远程存储库时,您需要执行git push origin master
(master是主分支)。从那时起,您只需执行git push
。
使用git push --tags
推送代码。
答案 30 :(得分:5)
在Stack Overflow帖子Tim's answer中认真添加Setup Git Server with Msysgit on Windows中的链接。
它完美地告诉我如何使用msysgit在Windows上设置Git,这是一篇非常详细的文章。
答案 31 :(得分:5)
WRT优秀的GUI /前端,您可能还想查看qgit这是Git的跨平台(Linux / Win32)存储库查看器,也可以用作最常见的Git的高级前端事实上,它可以通过所谓的“自定义操作”轻松增强,以便用户可以提供自定义操作。
答案 32 :(得分:5)
<强>资源强>: 请务必查看Scott Chacon's Gitcasts, especially the Railsconf talk 。
Github很棒,也有一些helpful guides。
答案 33 :(得分:5)
从 Pragmatic Guide to Git - Travis Swicegood
一书中获取的Rebase说明第三章
16。通过重新重写来重写历史重新提交是一个概念 Git里面没有对应的 传统版控制世界。 使用git rebase,你可以重写 各种存储库的历史 方式它是最多的之一 Git中强大的命令,这使得 它是最危险的之一。
rebase
需要进行一系列提交 (通常是一个分支)并重播它们 在另一个提交之上(通常是 最后一次提交在另一个分支)。该 父提交改变所以所有 重新计算提交ID。这个可以 给其他开发者带来问题 谁拥有你的代码因为ID 不匹配。有一个简单的经验法则 使用git rebase:尽可能多地使用它 想要本地提交。一旦你 与其他开发者共享更改, 头痛一般不值得 麻烦。
答案 34 :(得分:4)
我发现this post对于让我开始非常有用。我仍然需要阅读这本书和其他资源,但该帖子很有用,正如标题所说,“从概念上理解git”。我还建议服用Git&amp; GitHub课程在RubyLearning提供。
答案 35 :(得分:4)
我真正想到的另一个项目应该在这个列表中,可能对初学者非常有用:
如果我做了一些提交,然后我做了一些可怕的事情,比如可能是一个rebase,现在什么东西 - 甚至一切 - 似乎都丢失了怎么办? (Rebase似乎是第一次吸引大多数人的那个,所以我专注于它。虽然git rebase --abort
有很多帮助,但有时你会发现你在交互式rebase期间拙劣编辑了一个,让rebase完成,现在你想要恢复你的旧东西。然后有像filter-branch
...)
一个关键的git原则是它实际上从未删除你提交的任何内容。 (“什么,从来没有?”“不,永远不会!”“什么,从不?”“嗯,几乎没有!”)如果你还没有运行git gc
,它仍然是在那里。找到你以前的工作可能需要花些时间,但是如果你早些时候做了一些成功的git commit
,那么,即使是那些因悲剧性的rebase错误而显然失败的一系列提交仍然在那里,通常至少一个月(技术上,直到“reflogs”到期)。
重要的是要记住每个分支名称标记 - 或指向“提交ID”。这些是有趣的数字,如7cc5272
。您执行的许多操作(如向分支添加新提交)都会使分支名称指向新的不同提交ID。每个commit-ID都有一个指向某些先前commit-ID的链接,这实际上构成了一个充满提交的“分支”。
rebase条目谈论“重写历史”,而像git filter-branch
这样的命令也“重写历史”,但他们这样做不是通过破坏以前的历史,而是通过添加新历史。一旦新的历史记录到位,git将“移动标签”,使看起来像历史记录已经改变。如果您在fix-nasty-bug
分支上并执行git rebase
并设法破坏事物,则标签fix-nasty-bug
现在指的是残骸,但原始版本仍然存在。 Rebase特别使一个临时(非移动,非分支)标签拼写ORIG_HEAD
,让您找到它们。 filter-branch
命令也保存所有原始名称。在某些情况下,可能没有明显的名称,但始终可以找到提交。如果有必要,找一个“git guru”并解释你做了什么导致了残骸。
(命令git reflog show
也可以帮助查找提交ID。)
如果您发现了以前的部分或全部工作,请尝试:
git log <commit-ID> # ORIG_HEAD after a bad rebase, for instance
git show <commit-ID> # or some long SHA1 value you can still see in a window
如果它看起来正确或有用,请为其命名:
git branch recover-my-stuff ORIG_HEAD
然后又回来了!事实上,现在你的坏基础和你的原创作品都在你的git repo“永远”(或者至少,直到你删除分支名称和让几个月过去,然后他们得到垃圾收集)。您可以根据需要为所恢复的提交添加尽可能多的名称。 (分支名称几乎是免费的,除了杂乱你的git branch
输出,当然他们也保持提交不被垃圾收集。你也可以,或者更确切地说,将标签放在特定的提交ID上,如果你愿意的话那些。)
答案 36 :(得分:0)
关于合并冲突的非常好的帖子 - GitGuys: Merging With a Conflict - Conflicts And Resolutions
博客真的很棒 - 说明性,简洁的例子和可以理解的。绝对值得一试。