您的位置:首页 > 其它

分布式版本控制工具学习--Git

2009-12-21 13:17 597 查看
什么是分布式版本控制:



分布式版本控制
(DVCS)
是一种不需要中心服务器的管理文件版本的方法,但是它也可以使用中心服务器。更改可以被合并到
DVCS
的任何其他用户的系统中,因此可以实现非常灵活的工作流


DVCS



和集中式版本控制系统的主要差





:



DVCS

和集中式版本控制系统之间有三个关键差异。

第一个差异是,
DVCS

通过本地提交支持离线工作,这是由
DVCS

的操作方式决定的。这与集中式版本控制完全不同,集中式版本控制要求通过到中心服务器的连接执行所有操作。这种灵活性让开发人员在任何地方都能够像在办公室中一样轻松地工作,可以一次又一次地进行提交。

第二个差异是
DVCS

比集中式系统更灵活,因为
DVCS

支持许多不同类型的工作流,从传统的集中式工作流到纯粹的特殊工作流,再到特殊工作流和集中式工作流的组合。这种灵活性允许通过电子邮件、对等网络和开发团队喜欢的任何方式进行开发。

第三个差异是
DVCS

比集中式版本控制系统快得多,因为大多数操作在客户机上进行,速度非常快。另外,在需要进行推(
push

)操作(与另一个节点通信)时,速度也更快,因为两个客户机机器上都有完整的元数据。速度差异相当显著,根据使用本地存储库还是网络存储库,
DVCS


Subversion

快大约
3-10

倍。

目前的分布式版本控制工具:



Git

Mercurial

Bazaar

Git

基础:


(1)

Install Git:

On windows:

(1)

Tortoise Git: http://pixhawk.ethz.ch/wiki/toolchain/git/windows_git_installation
(2)

Msysgit: http://code.google.com/p/msysgit/downloads/list
(3)

Cygwin: http://www.cygwin.com/setup.exe
(2)

Config Git:

关于配置文件:


Windows
系统上,
Git
会找寻用户主目录下的
.gitconfig
文件。主目录即
$HOME
变量指定的目录,一般都是
C:/Documents and Settings/$USER
。此外,
Git
还会尝试找寻
/etc/gitconfig
文件,只不过看当初
Git
装在什么目录,就以此作为根目录来定位。

--global
è

” C:/Documents and Settings/$USER/.gitconfig”

--system
è


安装目录
/etc/gitconfig”

git config --global user.name "name"

git config --global user.email
“name@xx.com”

git config --global
--list

git config --global color.ui "always"

git config
--global
core.editor



c:/windows/system32/
notepad.exe”

(3)

Setup Initial Project Repository:

A.

Create a folder: mkdir MyGit

B.

Init the repository for the project:

cd MyGit

git init

C.

Add a file to the project repository

Make a new file desc

git
add desc => the file will be in the staging area then.

git commit –m “add a new file: desc” => the file will be in the repository then.

git status =>check the status of the working tree.

git
log => check the log info

D.

Branch & Tag & Merge

git branch test_r1.0 master
è

create a branch test_r1.0 based on the latest of master branch.

git checkout test_r1.0
è

switch to branch of test_r1.0 from master branch.

Add a new file “1”on the branch test_r1.0

git add 1

git commit –m “add a new file: 1 on branch test_r1.0”

git tag
TEST_REL_1 test_r1.0
è

make a tag on the branch of test_r1.0

git tag MASTER_REL_1 master
è

make a tag on the branch of master

git checkout test_r1.0

git rebase MASTER_REL_1
è

rebase test_r1.0 branch against MASTER_REL_1

git archive –format=zip –prefix=”Master_REL_1” master > Master_REL_1.zip

E.

Work with Remote Repository

git
clone <remote >
[local]

git clone http://github.com/tswicegood/mysite
深入学习:



(1)


Add


Commit:


(1)

Staged changes: Simply changes in your working tree that you want to tell your repository about.

(2)

Staging Area:
A place where set up the commits prior to commit to the repository.

(3)

git
add file |file list

A.

git add file

B.

git add file1 file2 …

C.

git add –i

*
** Commands ***

1: status 2: update 3: revert
4: add untracked

5: patch
6: diff
7: quit
8: help

Notes: 1. Status-check the status of the working tree.

2. update- generate a list of changes to be staged, you should select the change need to be updated.

3. Revert- generate a list of changes can be reverted, you should select the change need to be reverted.

4. Add untracked- add untracked files to the staging area.

5. Patch – You can choose which file or files you want to add

6. Diff – display the differences of the file in staging area and the repository.

(4)

Commit

A.

git commit –m “comments”
file1 file2 …
è

commit the specified file in staging area.

B.

git commit -m “comments”
è

commit all of the files in staging area.

C.

git commit -m “comments ” -a
è

commit all of the files in working tree.

D.

git commit –a
è

commit all of the files in working tree and add comments in prompted editor file.

(5)

Check the Status and differences

git
status

git diff
è

shows the difference between the working tree and
staging area(1) or repository(2).

git diff
--cached
è

shows the difference between staging area and the repository.

git diff
HEAD
è

shows the difference between working tree & staging area and the repository.

(6)

Manage files

A.

Rename or moving

git
mv source target

è

after this operation, the file in staging area.

B.

No copy command

C.

Ignore files:

a.

Add the files to be ignored in file .gitignore
è

A regular file tracked by the repository.

b.

Add the files to be ignored in .git/info/exclude
è

just in local

(7)
Some backward ways:

A. discards changes in the working tree:

git checkout <file>
è

discard the change in the working tre(not staged).

B. discards the staged content

git reset <file>

è

the file from the staging area to working tree.

git reset --hard
è

all changed from staging area to original

C. discards the last commit

git
revert commitid

(2)


Branches:



(1)

Rename a branch:

git
branch –m old_branch new_branch

(2)

List branches:

git branch

(3)

About merge:

A.

Straight merge: Take one branch and merge it into another branch. Pull the entire history of one branch into another.

git checkout target

git merge source
è

after finish this operation, the change will be in the repository.

B.

Squashing merge: Git takes all the history of one branch and compressed it into one commit in the other branch.

git checkout target

git merge --squash source
è

after finish this operation, the change will be in staging area.

git commit
-m “XXXXX”

C.

Cherry-pick:
Merge only one commit between branches and don’t do a full merge.

git checkout target

git
cherry-pick commit_id

è

may need handle conflicts, if no, it will commit automatically

git cherry-pick
-n commit_id

(4)

Conflicts handling:

A.

Config the merge tool

git config --global merge.tool kdiff3

git config --global mergetool.kdiff3.path "C:/Program Files/KDiff3/KDiff3.exe”

B.

Call the merge tool to handle the conflicts:

git mergetool

(5)

Delete Branch

在版本树上来看,用参数

”-d”

删除
branch

只是删去了
branch

的名字(类似于一个指向
HEAD

的指针),跟
clearcase

中不同,删掉了分支上的所有版本和改动。(前提:用“
-d

”删除分支时须在要删除分支
merge

到当前所在分支后操作)

用参数“
-D

”删除
branch,

 要删除的分支不需要
merge

到当前所在分支,可以强制性删除,但是在被删除分支上未被
merge

或打
tag

的内容也会被强制删除掉。

git branch -d branch_name
è

delete the branch only the content in this branch has been merge to the current branch.

If the merge hasn’t been performed, it will report:

Error: The branch “xxx” is not an ancestor of your current HEAD.

git branch –D branch_name
è

delete the branch forcely even the merge is not done.

(6)

Renaming Branch

git branch –m old_branch_name
new_branch_name
è

the new branch name should be a one doesn’t existed in the repository.

git branch –M old_branch_name
new_branch_name

è

the new branch name can be any. Careful when use this way.

(3)


History



A.

Log

git log

git log less
è

show logs in a screen by screen

git log commit_id
è

show log of a specified commit

git log commit_id
è

view the log starting at a given revision

git log --format=oneline

full/fuller/ short

/medium

/ full/

fuller/

emai/

raw


è

显示一行

git log -p
è

when show the log info, supply the diff at the same time.

B.

Specifying Revision Ranges

git
log --since=“5 hours”

git log –before=”5 hours”
-1

git log --after="2009-11.24”

git log commit_id1…commit_id2
è

show logs after commit_id1(old) to commit_id2(new), don’t include commit_id1(old) one.

git log commit_id1..HEAD
è

HEAD= the latest version of current branch

git log commit_id1..

è

same as the previous one

git log --pretty=”%h %s” Tag..HEAD

git log HEAD^^
è

”^” means the previous one before the specified point. Then “^^” means the one of two previous before the specified point.

git log Commit_id~N
è

“~N” means N previous before the specified point.

C.

Compare revision differences:

git diff commit_id
è

by default, it will compare commit_id and the HEAD

git diff --stat TAG
è

prints some statistics about change since TAG

git diff commit_id1 commit_id2
è

show difference between commit_id1 and commit_id2

git diff commit_id1..commit_id2
è

same as the previous one

git diff commit_id1…commit_id2

è

比较
commit_id2


commit_id1


commit_id2

的同源起始点

D.

Finding out who’s blame:

git blame filename
è

show change history of a file, “^” in output is for the first commit

git blame –L line1, line2 filename
è

show change history of a portion of a file

git blame –L line1, +2 filename
è

show the change history of line1 and line1+1

git blame –L /regular expression/ filename
è

show the history after the line matched with regular expression

git blame –L /regular expression/,+2 filename
è

show 2 lines from the matched line.

git blame –L
/regular expression/, line
commit_id^ -- filename

E.

Following Content:

Git can track the content when it moves within a file or even when it moves to another file.

Git tries to match at least three lines when it tries to detect a copy and paste.

git blame
è

Show what revision and author last modified each line of a file

git blame -M file ?????

è

至少要有
copy

三行
,

而且注意空行。

git blame –C –C file
è

detect moving and copy between files . “-C”detect lines copied from other files that were modified in the same commit. This is useful when you reorganize your program and move code around across files. When this option is given twice, the command additionally looks for copies from all other files in the parent for the commit that creates the file.

git log -C -C -1 –p
è

display the copy meta info in the log.

F.

Undoing changes:

About HEAD: head is (direct or indirect, i.e. symbolic) reference to the current commit.

ORIG_HEAD is previous state of HEAD.

a.

Amending commits:

git commit -C HEAD -a
--amend
è

“-C” reuse the comments of the specified commit, here is “HEAD”; “-c” invoke the editor, the user can further edit the commit message.

“--amend” can only be used when you’re working with the last commit. Rough equivalent to: git reset
--soft HEAD~1(


HEAD

前移,
then

当前的
head

变成
staging area); edit; git commit -c ORIG_HEAD

b.

Reverting Commit:

git revert
--no-edit commit_id
è

use the default commit message

git revert -n commit_id
è

Normally, in order to avoid the unnecessary conflicts, do revert from most recent first, and then backward.

c.

Resetting changes

git reset HEAD~1
è

HEAD will be in unstaged status, in this way, you can edit the code change in the previous commits and edit the commit information.

git reset
--soft
ORIG_HEAD
è

when you want to stage all of the previous commits but not want to commit them, you can use option ‘--soft’, then you can modify the previous commit by adding or taking away from it.

git reset
--hard HEAD~N
è

It removes your commits from repository and the working tree. It will reset to the N commit before the head.

G.

Rewriting history:

关于
rebase:
将当前的
head
切换到
source
部分,无论是对
branch

rebase
还是对某一个
version

rebase.

a.

Reordering commits:

git rebase -i HEAD~3
è

set the base with the commit of HEAD~3, in this way, you can handle the reorder of the three ones above HEAD~3. Edit the commit info in the editor for reordering, select command pick

Rebase
过程中如果有冲突,需要
git mergetool
解决冲突,然后继续
rebase,

git rebase –continue

b.

Squash Commits:

git rebase -i HEAD~3
è

edit the commit info in the editor, push the squashed object together and select squash command for the following ones to be squashed.

Eg.
pick 1

Squash 2

Then 1 and 2 will be squashed.

c.

Break one commit into multiple commits:

git rebase -i HEAD~4
è


HEAD
至于
HEAD~4
,编辑提交的
comments,

pick
改为
edit.
然后
git reset HEAD~1,

HEAD~4..HEAD
的改动置到
unstaged
状态以便对内容就行修改,分别处理要拆分的文件内容,分别
commit

repository.
然后
git rebase --continue.

(4)


Remote Repository:



A.

Protocols with remote repository:

SSH
è

high security (requires proper user permissions)

Git
è

high speed

HTTP/HTTPS
è

get used to firewall(requires a working WebDAV server.)

B.

Keeping up to date:

a.

git
clone remote_server

git branch –r
è

shows branches on remote server.

git fetch remote_server

è

updates remote branches, but don’t do merge to local branch
.

b.

git pull remote_server branch
è

fetch the remote repository and merge to local branch at the same time. If without default remote configuration, should supply the branch which should be merged to, should without prefix of origin (origin is the default remote repository name assigned to a repository that you create a clone from)

c.

git push
è

First, it assumes you’re pushing to your origin repository. Second, it assumes you’re pushing the current branch on your repository to its counterpart on the remote repository if that branch exists remotely.

git push <remote>
è

<remote> is the current branch's remote (or

origin
, if no

remote is configured for the current branch).

git
push origin local_branch

è


local_branch

上的东西
push


origin
repository,

如果
origin repository

中不存在与
local_branch

同名的
branch

会创建出新的同名
branch.

git push --dry-run
è

just look but not merge exactly

Push
不会影响
remote
端的
working tree
。当
remote

working tree
就是处在接


push
内容的
branch
上时,完成
push
操作后,
remote
端在获得
push
之前的
HEAD
内容会变成
staged
状态,从而进一步进行冲突处理和内容确认。

C.

Add new remote repository:

a.

git remote add origin <remote_repository>
è

can add alias for remote repository.

b.

git remote show remote_repository

(5)


organizing repository:



A.

Tag for milestone:

git tag TAG_NAME
è

make a tag

git tag
è

show tags

git checkout –b tag
è

make a branch based on a tag.

B.

Multiple Projects, One Repository:

This works well for projects that need to have a common history, such as a project that is made up of several components that are all released together.

With multiple projects on independent release schedules, the number
of branches and tags you have to create will increase exponentially. Repositories are lightweight in Git, though, so creating one repository for each project isn’t difficult.

C.

Multiple Projects, Multiple Repositories:

D.

Git submodules:

track multiple repositories as if they’re all in the same repository.

These allow you to store a repository within another repository while keeping the two histories completely independent.

a.

Add new submodule:
è

After this step, git set to staging area

prompt>git submodule add
repository alias

eg. git submodule add C:/Practice/091209 child

b.

Check submould list:

prompt>git submodule

-961dff5c546cfc37c4824f220712e2d99536dd67 child
è

”-”means the repository hasn’t been initialized.

c.

Initialize submodule

prompt>git submodule init child

Submodule 'child' (C:/Practice/091209) registered for path 'child'

è

This adds an entry to
.git/config
so Git understands that the
hocus
directory

contains a submodule.

d.

Clone a repository with submodules:

Prompt>mkdir clone

Prompt>cd clone

Prompt>git clone //cnbjw2762/091210 new_091210

Prompt> git submodule

-961dff5c546cfc37c4824f220712e2d99536dd67 child

Prompt>git submodule init child

Submodule 'child' (C:/Practice/091209) registered for path 'child'

Prompt>git submodule update child

Initialized empty Git repository in C:/Practice/clone/new_091210/child/.git/

Submodule path 'child': checked out '961dff5c546cfc37c4824f220712e2d99536dd67'

e.

Gotchas

Git
submodule update is destructive, running the update command will overwrite any changes you have in your submodule that have not been committed

. Be sure to doublecheck your submodule’s working tree for changes before running git submodule update to correct changes.

(6)


Beyond Basics:



A.

Compact Repository history:

git gc [--aggressive]
è

don’t change the history, but the stored way.

B.

Exporting Repository:

git archive --format=zip --prefix=proj1_rel/
HEAD >proj1_rel.zip
è

Notice that there’s a trailing forward slash at the end of mysite-release/. Without that, git archive adds the string to the beginning of eery filename rather than putting in a direcoty.

git archive --format=tar –prefix=proj1_rel/ HEAD | gzip > proj1_rel.tar.gz

C.

Rebase a branch:

git rebase <Tag/Commit/Branch> [<branch>]
è

Git change head to the specified Tag/commit/branch first. If specified branch, git will checkout the branch first.

git rebase

git mergetool

git rebase --continue/--skip/--abort

E---F---G---H---I---J
topicA

git rebase --onto topicA~5 topicA~3 topicA

E---H'---I'---J'
topicA

Note: git rebase --onto new_base ignore_part branch

D.

Reflog

git reflog

E.

Bisecting Your Repository

git bisect start

git bisect bad

git bisect good commit/tag

git bisect reset

git bisect visualize

git bisect log

git bisect replay file
è

copy the output of git bisect log to a file, delete the content after the mistake, take this file as the parameter of git bisect replay.

git bisect start HEAD R1.0
è


number
文件进行
bisect

number file


aa

bb

cc

dd

11

22

33

44

git bisect run script

script eg:

#! C:/Perl/bin/Perl.exe

open (FL,"C:/Practice/test/number");

@input=<FL>;

close FL;

$count=scalar(@input);

print $count;

print $input[$count-1];

if ($input[$count-1]=~//d+/)

{

exit 1;

}

else

{

exit 0;

}

(7)

System

A.

Import SVN into Git:

git svn clone -prefix svn/ -s svn://svnrepo/sunshine

B.

Running Git server on Gitosis

a.

Install python.

b.

Install easyinstall:
http://peak.telecommunity.com/DevCenter/EasyInstall
Note:

(1)


Windows

环境下,
HEAD^

无效,如果想使之有效,需要加引号
,”HEAD^”

(2)

/etc/gitconfig
文件:系统中对所有用户都普遍适用的配置。若使用

git config

时用

--system

选项,读写的就是这个文件。

(3)

~/.gitconfig
文件:用户目录下的配置文件只适用于该用户。若使用

git config

时用

--global

选项,读写的就是这个文件。

(4)

当前项目的
git
目录中的配置文件(也就是工作目录中的

.git/config

文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以

.git/config

里的配置会覆盖

/etc/gitconfig

中的同名变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: