Git教程【译】(二)
5. 远端仓库(remote repositories)5.1. 设置一个远端的Git仓库
我们将创建一个远端的Git仓库。这个仓库可以存储在本地或者是网络上。
远端Git仓库和标准的Git仓库有如下差别:一个标准的Git仓库包括了源代码和历史信息记录。我们可以直接在这个基础上修改代码,因为它已经包含了一个工作副本。但是远端仓库没有包括工作副本,只包括了历史信息。可以使用--bare选项来创建一个这样的仓库。
为了方便起见,示例中的仓库创建在本地文件系统上
[*]# Switch to the first repository
[*]cd ~/repo01
[*]#
[*]git clone --bare . ../remote-repository.git
[*]
[*]# Check the content, it is identical to the .git directory in repo01
[*]ls ~/remote-repository.git
5.2. 推送更改到其他的仓库
做一些更改,然后将这些更改从你的第一个仓库推送到一个远端仓库
[*]# Make some changes in the first repository
[*]cd ~/repo01
[*]
[*]# Make some changes in the file
[*]echo "Hello, hello. Turn your radio on" > test01
[*]echo "Bye, bye. Turn your radio off" > test02
[*]
[*]# Commit the changes, -a will commit changes for modified files
[*]# but will not add automatically new files
[*]git commit -a -m "Some changes"
[*]
[*]# Push the changes
[*]git push ../remote-repository.git
5.3. 添加远端仓库
除了通过完整的URL来访问Git仓库外,还可以通过git remote add命令为仓库添加一个短名称。当你克隆了一个仓库以后,origin表示所克隆的原始仓库。即使我们从零开始,这个名称也存在。
[*]# Add ../remote-repository.git with the name origin
[*]git remote add origin ../remote-repository.git
[*]
[*]# Again some changes
[*]echo "I added a remote repo" > test02
[*]# Commit
[*]git commit -a -m "This is a test for the new remote origin"
[*]# If you do not label a repository it will push to origin
[*]git push origin
5.4. 显示已有的远端仓库
通过以下命令查看已经存在的远端仓库
[*]# Show the existing defined remote repositories
[*]git remote
5.5. 克隆仓库
通过以下命令在新的目录下创建一个新的仓库
[*]# Switch to home
[*]cd ~
[*]# Make new directory
[*]mkdir repo02
[*]
[*]# Switch to new directory
[*]
[*]cd ~/repo02
[*]# Clone
[*]git clone ../remote-repository.git .
5.6. 拉取(Pull)更改
通过拉取,可以从其他的仓库中获取最新的更改。在第二个仓库中,做一些更改,然后将更改推送到远端的仓库中。然后第一个仓库拉取这些更改
[*]# Switch to home
[*]cd ~
[*]# Switch to second directory
[*]cd ~/repo02
[*]# Make changes
[*]echo "A change" > test01
[*]# Commit
[*]git commit -a -m "A change"
[*]# Push changes to remote repository
[*]# Origin is automatically maintained as we cloned from this repository
[*]git push origin
[*]# Switch to the first repository and pull in the changes
[*]cd ~/repo01
[*]git pull ../remote-repository.git/
[*]# Check the changes
[*]less test01
6. 还原更改
如果在你的工作副本中,你创建了不想被提交的文件,你可以丢弃它。
[*]# Create a new file with content
[*]touch test04
[*]echo "this is trash" > test04
[*]
[*]# Make a dry-run to see what would happen
[*]# -n is the same as --dry-run
[*]git clean -n
[*]
[*]# Now delete
[*]git clean -f
你可以提取老版本的代码,通过提交的ID。git log命令可以查看提交ID
[*]# Switch to home
[*]cd ~/repo01
[*]# Get the log
[*]git log
[*]
[*]# Copy one of the older commits and checkout the older revision via译者注:checkout
[*]后加commit id就是把commit的内容复制到index和工作副本中
[*]git checkout commit_name
如果你还未把更改加入到索引中,你也可以直接还原所有的更改
[*]#Some nonsense change
[*]echo "nonsense change" > test01
[*]# Not added to the staging index. Therefore we can
[*]# just checkout the old version
[*]#译者注:checkout后如果没有commit id号,就是从index中拷贝数据到工作副本,不涉及commit部分的改变
[*]git checkout test01
[*]# Check the result
[*]cat test01
[*]# Another nonsense change
[*]echo "another nonsense change" > test01
[*]# We add the file to the staging index
[*]git add test01
[*]# Restore the file in the staging index
[*]#译者注:复制HEAD所指commit的test01文件到index中
[*]git reset HEAD test01
[*]# Get the old version from the staging index
[*]#译者注:复制index中test01到工作副本中
[*]git checkout test01
[*]#译者注,以上两条命令可以合并为git checkout HEAD test01
也可以通过revert命令进行还原操作
[*]# Revert a commit
[*]git revert commit_name
即使你删除了一个未添加到索引和提交的文件,你也可以还原出这个文件
[*]# Delete a file
[*]rm test01
[*]# Revert the deletion
[*]git checkout test01
如果你已经添加一个文件到索引中,但是未提交。可以通过git reset file 命令将这个文件从索引中删除
[*]// Create a file
[*]touch incorrect.txt
[*]// Accidently add it to the index
[*]git add .
[*]// Remove it from the index
[*]git reset incorrect.txt
[*]// Delete the file
[*]rm incorrect.txt
如果你删除了文件夹且尚未提交,可以通过以下命令来恢复这个文件夹 。译者注:即使已经提交,也可以还原
[*]git checkout HEAD -- your_dir_to_restore
译者注:checkout和reset这两个命令的含义是不同的,可以参阅这篇文章http://marklodato.github.com/visual-git-guide/index-en.html
7. 标记
Git可以使用对历史记录中的任一版本进行标记。这样在后续的版本中就能轻松的找到。一般来说,被用来标记某个发行的版本
可以通过git tag命令列出所有的标记,通过如下命令来创建一个标记和恢复到一个标记
[*]git tag version1.6 -m 'version 1.6'
[*]git checkout
8. 分支、合并
8.1. 分支
通过分支,可以创造独立的代码副本。默认的分支叫master。Git消耗很少的资源就能创建分支。Git鼓励开发人员多使用分支
下面的命令列出了所有的本地分支,当前所在的分支前带有*号
[*]git branch
如果你还想看到远端仓库的分支,可以使用下面的命令
[*]git branch -a
可以通过下面的命令来创建一个新的分支
[*]#Syntax: git branch
[*]#in the above is optional
[*]# if not specified the last commit will be used
[*]# If specified the corresponding commit will be used
[*]git branch testing
[*]# Switch to your new branch
[*]git checkout testing
[*]# Some changes
[*]echo "Cool new feature in this branch" > test01
[*]git commit -a -m "new feature"
[*]# Switch to the master branch
[*]git checkout master
[*]# Check that the content of test01 is the old one
[*]cat test01
8.2. 合并
通过Merge我们可以合并两个不同分支的结果。Merge通过所谓的三路合并来完成。分别来自两个分支的最新commit和两个分支的最新公共commit
可以通过如下的命令进行合并
[*]# Syntax: git merge
[*]git merge testing
一旦合并发生了冲突,Git会标志出来,开发人员需要手工的去解决这些冲突。解决冲突以后,就可以将文件添加到索引中,然后提交更改
8.3. 删除分支
删除分支的命令如下:
[*]#Delete branch testing
[*]git branch -d testing
[*]# Check if branch has been deleted
[*]git branch
8.4. 推送(push)一个分支到远端仓库
默认的,Git只会推送匹配的分支的远端仓库。这意味在使用git push命令默认推送你的分支之前,需要手工的推送一次这个分支。
[*]# Push testing branch to remote repository
[*]git push origin testing
[*]
[*]# Switch to the testing branch
[*]git checkout testing
[*]
[*]# Some changes
[*]echo "News for you" > test01
[*]git commit -a -m "new feature in branch"
[*]
[*]# Push all including branch
[*]git push
通过这种方式,你可以确定哪些分支对于其他仓库是可见的,而哪些只是本地的分支
9. 解决合并冲突
如果两个不同的开发人员对同一个文件进行了修改,那么合并冲突就会发生。而Git没有智能到自动解决合并两个修改
在这一节中,我们会首先制造一个合并冲突,然后解决它,并应用到Git仓库中
下面会产生一个合并冲突
[*]# Switch to the first directory
[*]cd ~/repo01
[*]# Make changes
[*]touch mergeconflict.txt
[*]echo "Change in the first repository" > mergeconflict.txt
[*]# Stage and commit
[*]git add . && git commit -a -m "Will create merge conflict 1"
[*]
[*]# Switch to the second directory
[*]cd ~/repo02
[*]# Make changes
[*]touch mergeconflict.txt
[*]echo "Change in the second repository" > mergeconflict.txt
[*]# Stage and commit
[*]git add . && git commit -a -m "Will create merge conflict 2"
[*]# Push to the master repository
[*]git push
[*]
[*]# Now try to push from the first directory
[*]# Switch to the first directory
[*]cd ~/repo01
[*]# Try to push --> you will get an error message
[*]git push
[*]# Get the changes
[*]git pull origin master
Git将冲突放在收到影响的文件中,文件内容如下:
[*]> b29196692f5ebfd10d8a9ca1911c8b08127c85f8
上面部分是你的本地仓库,下面部分是远端仓库。现在编辑这个文件,然后commit更改。另外的,你可以使用git mergetool命令
[*]# Either edit the file manually or use
[*]git mergetool
[*]# You will be prompted to select which merge tool you want to use
[*]# For example on Ubuntu you can use the tool "meld"
[*]# Aftermerging the changes manually, commit them
[*]git commit -m "merged changes"
10. 变基(Rebase)
10.1. 在同一分支中应用Rebase Commit
通过rebase命令可以合并多个commit为一个。这样用户push更改到远端仓库的时候就可以先修改commit历史
接下来我们将创建多个commit,然后再将它们rebase成一个commit
[*]# Create a new file
[*]touch rebase.txt
[*]
[*]# Add it to git
[*]git add . && git commit -m "rebase.txt added to index"
[*]
[*]# Do some silly changes and commit
[*]echo "content" >> rebase.txt
[*]git add . && git commit -m "added content"
[*]echo " more content" >> rebase.txt
[*]git add . && git commit -m "added more content"
[*]echo " more content" >> rebase.txt
[*]git add . && git commit -m "added more content"
[*]echo " more content" >> rebase.txt
[*]git add . && git commit -m "added more content"
[*]echo " more content" >> rebase.txt
[*]git add . && git commit -m "added more content"
[*]echo " more content" >> rebase.txt
[*]git add . && git commit -m "added more content"
[*]
[*]# Check the git log message
[*]git log
我们合并最后的七个commit。你可以通过如下的命令交互的完成
[*]git rebase -i HEAD~7
这个命令会打开编辑器让你修改commit的信息或者 squash/ fixup最后一个信息。
Squash会合并commit信息而fixup会忽略commit信息(待理解)
10.2. Rebasing多个分支
你也可以对两个分支进行rebase操作。如下所述,merge命令合并两个分支的更改。rebase命令为一个分支的更改生成一个补丁,然后应用这个补丁到另一分支中。
使用merge和rebase,最后的源代码是一样的,但是使用rebase产生的commit历史更加的少,而且历史记录看上去更加的线性
[*]# Create new branch
[*]git branch testing
[*]# Checkout the branch
[*]git checkout testing
[*]# Make some changes
[*]echo "This will be rebased to master" > test01
[*]# Commit into testing branch
[*]git commit -a -m "New feature in branch"
[*]# Rebase the master
[*]git rebase master
10.3.Rebase最佳实践
在push更改到其他的Git仓库之前,我们需要仔细检查本地分支的commit历史
在Git中,你可以使用本地的commit。开发人员可以利用这个功能方便的回滚本地的开发历史。但是在push之前,需要观察你的本地分支历史,是否其中有些commit历史对其他用户来说是无关的
如果所有的commit历史都跟同一个功能有关,很多情况下,你需要rebase这些commit历史为一个commit历史。
交互性的rebase主要就是做重写commit历史的任务。这样做是安全的,因为commit还没有被push到其它的仓库。这意味着commit历史只有在被push之前被修改
如果你修改然后push了一个已经在目标仓库中存在的commit历史,这看起来就像是你实现了一些别人已经实现的功能
页:
[1]