您的位置:首页 > 其它

Git基本概念及操作(2)

2012-04-20 13:24 393 查看
想要深入的了解GIT,还得回到常见版本管理系统中的version概念。前面我们说到一个文件在不同的时间会产生不同的版本,那版本管理系统怎么记录这些不同的版本,是每一个时间保存一个文件,还是保存这些差异点,然后合并呢?这里通常有两种实现方式,一种是保存变更差异,如下图所示:



这种方式广泛采用在CVS/SVN中,好处是管理系统保存单个版本所用的空间不需要很大。但坏处很明显,比喻说我在版本4处想要拿到File A/B/C的拷贝,需要经过三次比较计算才能拿到准备的版本数据。并且这当中任何一个版本数据丢失了我就不能得到当前版本数据。第二种是每次都保存,只要有变化就保存。如下图所示:



这种方式就是对每一个版本的每一个文件进行HASH计算,一旦发现HASH不同就诞生一个新的文件,如果相同说明文件没变化。因此,这种管理下每个版本实际是保存单独的文件,与前一个版本不需要进行差异化比较。取出一个新版本的效率大大增强。所获得的好处是非常明显的。GIT就是采用这种方案的。GIT采用SHA-1计算出每种管理对象(Element)的HASH值,通过这些HASH值来组成一个管理对象树。
前面我们讲的集中式版本管理系统通常都是C/S架构,一个Repository,多个Client。那么对GIT这种分布式版本管理系统,其基本架构怎么样呢?其实也类似,只是说C/S都在本地。GIT对源码的管理分成三块,一块是Repository通常是以.git目录下保存的数据,一块是工作区 working area,是与.git目录同级的其它目录及子目录都是工作区,注意工作区中不一定是所有的文件都是受控的,只有当你的文件加入REPO后才是受控的。第三块就是比较难以理解的暂定区staging area. Staging area实际上是.git目录中一个索引文件,也就是这个文件的HASH值。如下图所示:



其中Working directory是项目的检出版本,这个检出版本跟你当前的工作分支是相关的。缺省工作分支是master。这个有点类似于CC中VIEW概念。一旦你将当前工作目录中的所有文件都commit后,这些目录中的文件实际上是可以删除的。这一点同CC中VIEW非常相似。Staging area是一个记录暂存区,在GIT目录中表现为索引文件,与正式COMMIT区别就是状态未变。如下图所示:



了解了上面两大基本概念之后,我们可以结合实际操作来深入了解GIT的一些基本理念,这些理念实际上也就是在GIT下是如何定义版本与分支、TAG、HEAD及其之间的关系。
【1】GIT配置。GIT目前是没有权限系统的,或者说权限非常弱的。GIT的权限目前主要是靠操作系统,所以GIT配置中是没有权限配置的。GIT配置分成全局配置、用户配置和项目配置。全局配置适用于操作系统的所有用户,用户配置适用于当前用户,项目配置适用于当前项目。每一个级别的配置都会覆盖上层的相同配置。这三种配置区别在于存储目录和使用命令选项不同。
1)全局配置 /etc/gitconfig(相对于安装路径,有时候没有) 命令git config –system
2)用户配置 ~/.gitconfig 或者$HOME/.gitconfig git-config –global
3)项目配置 项目.git目录中config目录下 git config
[root@wrlinux3 mygit]# cat /root/.gitconfig
[core]
    gitproxy = /work/bongos/bin/git-proxy
[merge]
    tool = vimdiff
[root@wrlinux3 mygit]# ls -latr /etc/gitconfig
ls: cannot access /etc/gitconfig: No such file or directory
[root@wrlinux3 mygit]# ls -latr ~/.gitconfig
-rw-r--r--. 1 root root 70 Apr 20 16:01 /root/.gitconfig
[root@wrlinux3 mygit]# ls -latr .git/config
.git/   test.c 
[root@wrlinux3 mygit]# ls -latr .git/config
-rw-r--r--. 1 root root 92 Apr 20 15:27 .git/config
[root@wrlinux3 mygit]# git config --list
core.gitproxy=/work/bongos/bin/git-proxy
merge.tool=vimdiff
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true

[root@wrlinux3 mygit]# git config --global user.name "ROOT root"
[root@wrlinux3 mygit]# git config --global user.emal "root@root.com"
[root@wrlinux3 mygit]# cat ~/.gitconfig
[core]
    gitproxy = /work/bongos/bin/git-proxy
[merge]
    tool = vimdiff
[user]
    name = ROOT root
    emal = root@root.com
[root@wrlinux3 mygit]# git config user.name "PROJ proj"
[root@wrlinux3 mygit]# git config user.email "proj@proj.com"
[root@wrlinux3 mygit]# cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[user]
    name = PROJ proj
    email = proj@proj.com
[root@wrlinux3 mygit]# git config --list
core.gitproxy=/work/bongos/bin/git-proxy
merge.tool=vimdiff
user.name=ROOT root
user.emal=root@root.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=PROJ proj
user.email=proj@proj.com
[root@wrlinux3 mygit]# git config user.name
PROJ proj
[root@wrlinux3 mygit]# git config --global user.name
ROOT root
[root@wrlinux3 mygit]#
GIT配置还有三个其他配置,一个就是命令的自动完成,还有一个命令别名。最后一个就是gitignore .自动完成需要一个BASH,这个文件通常在contrib目录下,需要进行如下图所示的配置:



别名是使用git config 来定义alias.*
1008  git config --global alias.co checkout
1009  git config --global alias.br branch
1010  git config --global alias.ci commit
1011  git config --global alias.st status
1012  git config --global alias.unstage 'reset HEAD --'
1013  git config --global alias.last 'log -1 HEARD'
1014  git last
1015  git config --global alias.last 'log -l HEAD'
1016  git last
1017  git log -l
1018  git log -1 HEAD
1019  git help log
1020  git log -1 HEAD
1021  git log -l HEAD
1022  history
[root@wrlinux3 mygit]# git config --list
core.gitproxy=/work/bongos/bin/git-proxy
merge.tool=vimdiff
user.name=ROOT root
user.emal=root@root.com
alias.co=checkout
alias.br=branch
alias.ci=commit
alias.st=status
alias.unstage=reset HEAD --
alias.last=log -l HEAD
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=PROJ proj
user.email=proj@proj.com
[root@wrlinux3 mygit]#
对一个项目如果不想将工作目录中一些临时或者编译产生的文件纳入git管理,可以通过创建.gitignore文件来告诉git。



【2】仓库建立。建立GIT项目仓库,一种是完全新的创建,也就是说让项目所在的目录成为GIT受控,只需要执行命令git init,另一种是别的已有的克隆一个出来,执行git clone 如git clone git://github.com/schacon/grit.git。
[root@wrlinux3 mygit]# git init
Reinitialized existing Git repository in /work/bongos/mygit/.git/
[root@wrlinux3 mygit]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   test.c
#
[root@wrlinux3 mygit]# ls
test.c
[root@wrlinux3 mygit]# vi README
[root@wrlinux3 mygit]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   test.c
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    README
[root@wrlinux3 mygit]#
GIT是分布式,GIT在任何一个地方的仓库都保存全部的信息,但绝大部分项目团队为了开发协同的需要,通常建立一个远程仓库来协同相互之间的开发,也就是说大家都与远程仓库进行同步,就实现了相互之间的同步。GIT本地与远程之间支持多种协议,常见git/https等。远程仓库通常以URL形貌提供,但实际上它是一个有命名的。通常默认是origin。对远程仓库如何操作管理,有一些常用的命令,如下:
1)查看远程库 git remote –v  或者git remote show origin
[root@wrlinux3 android]# git remote -v
origin    git://git.videolan.org/vlc-ports/android.git (fetch)
origin    git://git.videolan.org/vlc-ports/android.git (push)
[root@wrlinux3 android]# git remote
origin
[root@wrlinux3 android]# git remote show origin
* remote origin
  Fetch URL: git://git.videolan.org/vlc-ports/android.git
  Push  URL: git://git.videolan.org/vlc-ports/android.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (local out of date)
[root@wrlinux3 android]#
2)添加远程库 git remote add pt git://github.com/paulboone/ticgit.gi
3)抓取数据  git fetch pb这里有两个需要注意的是无端分支与本地分支它不是自动合并的到本地分支的。
[root@wrlinux3 android]# git fetch origin
remote: Counting objects: 86, done.
remote: Compressing objects: 100% (50/50), done.
remote: Total 60 (delta 40), reused 0 (delta 0)
Unpacking objects: 100% (60/60), done.
From git://git.videolan.org/vlc-ports/android
   628d90c..b88d59d  master     -> origin/master
[root@wrlinux3 android]# cd vlc
4)推送数据 git push origin master
5)删除远程仓库 git remote rename pb paul或者git remote rm paul
【3】git常用操作 GIT的操作方式与一般的SCM不同,通常的SCM是先检出后工作再受近。GIT是在创建仓库之后就可以对当前文件进行修改,也就是说默认状态下所有文件都是可以修改的。修改后文件用户可以提交仓库GIT进行监管。如下图所示:



下面将常用的操作命令结合起来示例如下图所示:



下面演示一些常用的操作,这些操作包括删除文件、重命名文件、撤消提交、撤消跟踪、撤消修改及查看日志:
1)删除,采用git rm,单独的rm只会将工作区中文件删除,仓库中没有删除,还有可能通过checkout检出来进行恢复。如果使用git rm则会将文件从仓库中删除,不能恢复。
[root@wrlinux3 mygit]# git status
# On branch master
nothing to commit (working directory clean)
[root@wrlinux3 mygit]# ls
README  test.c
[root@wrlinux3 mygit]# rm README
rm: remove regular file `README'? y
[root@wrlinux3 mygit]# git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    deleted:    README
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@wrlinux3 mygit]# git checkout README
[root@wrlinux3 mygit]# ls
README  test.c
[root@wrlinux3 mygit]# git rm README
rm 'README'
[root@wrlinux3 mygit]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    deleted:    README
#
[root@wrlinux3 mygit]# ls -latr
total 16
drwxr-xr-x. 12 root root 4096 Apr 20 15:27 ..
-rw-r--r--.  1 root root   18 Apr 20 15:27 test.c
drwxr-xr-x.  3 root root 4096 Apr 26 16:35 .
drwxr-xr-x.  8 root root 4096 Apr 26 16:35 .git
[root@wrlinux3 mygit]# git checkout README
error: pathspec 'README' did not match any file(s) known to git.
[root@wrlinux3 mygit]# git commit -m "delete "
[master 24c6871] delete
1 file changed, 7 deletions(-)
delete mode 100644 README
[root@wrlinux3 mygit]# git statue
git: 'statue' is not a git command. See 'git --help'.
Did you mean this?
    status
[root@wrlinux3 mygit]# git st
# On branch master
nothing to commit (working directory clean)
[root@wrlinux3 mygit]#
2)重命名文件,相当于先删除后加入 git mv
[root@wrlinux3 mygit]# vi readme
[root@wrlinux3 mygit]# git commit -a -m "new readme commit"
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    readme
nothing added to commit but untracked files present (use "git add" to track)
[root@wrlinux3 mygit]# git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    readme
nothing added to commit but untracked files present (use "git add" to track)
[root@wrlinux3 mygit]# git commit -a -m "new readme commit"
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    readme
nothing added to commit but untracked files present (use "git add" to track)
[root@wrlinux3 mygit]# ls
readme  test.c
[root@wrlinux3 mygit]# git add readme
[root@wrlinux3 mygit]# git commit -a -m "new readme commit"
[master e529597] new readme commit
1 file changed, 1 insertion(+)
create mode 100644 readme
[root@wrlinux3 mygit]# git status
# On branch master
nothing to commit (working directory clean)
[root@wrlinux3 mygit]# git mv readme README
[root@wrlinux3 mygit]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    renamed:    readme -> README
#
[root@wrlinux3 mygit]# git commit -a -m "move file name"
[master 1868051] move file name
1 file changed, 0 insertions(+), 0 deletions(-)
rename readme => README (100%)
[root@wrlinux3 mygit]# git status
# On branch master
nothing to commit (working directory clean)
3)git log 可以显示操作日志,有多种方式,格式化也行,使用gitk图形化展示也可以。
[root@wrlinux3 mygit]# git log
commit 1868051cb93d4223a27f91b55b15e5b1cc3ab980
Author: PROJ proj <proj@proj.com>
Date:   Thu Apr 26 16:44:18 2012 +0800
    move file name
commit e529597105dded8688536ab5b37118e2597f8956
Author: PROJ proj <proj@proj.com>
Date:   Thu Apr 26 16:43:19 2012 +0800
    new readme commit
commit 24c68710bad22d65319acb3776ea70ca1720df0a
Author: PROJ proj <proj@proj.com>
Date:   Thu Apr 26 16:37:43 2012 +0800
    delete
commit 5399ad857c13085e00af125f04e5d3be2d22febc
Author: PROJ proj <proj@proj.com>
Date:   Wed Apr 25 17:31:12 2012 +0800
    the forth commit
commit 5cb0791c037545f3167c6af179a13dbdd5f395fe
Author: PROJ proj <proj@proj.com>
Date:   Wed Apr 25 17:30:07 2012 +0800
    third commit
commit 1776744b25f0c15d1d3947307bbf9aaf7cefbb7e
Author: PROJ proj <proj@proj.com>
Date:   Wed Apr 25 15:24:05 2012 +0800
    second commit
[root@wrlinux3 mygit]#
4)撤消暂存文件 git reset HEAD filename
[root@wrlinux3 mygit]# vi teset1.c
[root@wrlinux3 mygit]# git add teset1.c
[root@wrlinux3 mygit]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    new file:   teset1.c
#
[root@wrlinux3 mygit]# git reset HEAD teset1.c
[root@wrlinux3 mygit]# git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    teset1.c
nothing added to commit but untracked files present (use "git add" to track)
[root@wrlinux3 mygit]#
5)撤消当前的修改,如果当前的修改还未提交,不想修改时,可以使用checkout恢复,但是修复仅限于两个状态之间,也就是如果文件当前在COMMIT时,可以直接恢复工作区的版本。如果当前文件在STAGE时,这时只能用RESET来恢复。 [root@wrlinux3 mygit]# vi test.c
[root@wrlinux3 mygit]# git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    modified:   test.c
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    teset1.c
no changes added to commit (use "git add" and/or "git commit -a")
[root@wrlinux3 mygit]# git checkout test.c
[root@wrlinux3 mygit]# git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    teset1.c
nothing added to commit but untracked files present (use "git add" to track)
[root@wrlinux3 mygit]# vi tes
6)撤消提交操作git commit --amend
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: