Suse使用初体验

这两天折腾了一下SuseSLES 12 Beta版本),感觉和RedHat系列还是有一些不同。记录下来,以备以后查找:

(1)YaST2

YaST (Yet another Setup Tool)2Suse系统上的配置工具的:

Capture

感觉很好用。配置网络,FTPProxy等等,很方便。另外,单击图标就可以启动软件了,让用惯了“双击”的我开始不大适应。

(2)zypper

命令行安装软件使用zypper命令(in代表install):

zypper in git-core

卸载(rm):

zypper rm git-core

另外注意,git包的名字叫git-core

(3)命令窗口

使用Alt + F2快捷键可以调出命令窗口:

Capture1

输入gnome-terminal可以打开一个终端。

(4)supportconfig

Suse提供了supportconfig工具,用来抓取系统的信息,对debugging提供了很大的帮助:

Capture

 

 

git branch & merge笔记

In fact, in Git, the act of creating a new branch is simply writing a file in the .git/refs/heads directory that has the SHA-1 of the last commit for that branch.

Creating a branch is nothing more than just writing 40 characters to a file.

Switching to that branch simply means having Git make your working directory look like the tree that SHA-1 points to and updating the HEAD file so each commit from that point on moves that branch pointer forward (in other words, it changes the 40 characters in .git/refs/heads/[current_branch_name] be the SHA-1 of your last commit).

可以看到,在git中,创建一个branch仅仅是在一个文件中加入40个字符的SHA-1值。

Remotes are basically pointers to branches in other peoples copies of the same repository, often on other computers. If you got your repository by cloning it, rather than initializing it, you should have a remote branch of where you copied it from automatically added as origin by default. Which means the tree that was checked out during your initial clone would be referenced as origin/master , which means “the master branch of the origin remote.”

Remotes是指向其它人关于这个repository copy里某个branch的指针。如果你的repository是通过clone其它copy得到的,而不是initialize的,在你的repository里,会自动产生一个origin/masterremote branch指向你copyrepository tree

参考资料:
Git internals

Git数据模型笔记

Git object数据是一个有向无环图,即从任何一个commit出发都可以遍历其任何的parent,但绝不会有环。每个commit都指向一个tree,而一个tree则指向了一个或多个tree和(或)blob

Git数据模型如下图所示:

1

以下面目录结构为例:

2

工作目录下包含了两个目录和三个文件。初始化的git数据模型如下:

3

当修改lib/base/base_include.rb这个文件并提交以后,会产生一个新的blob以及相应的新tree。在当前commit打出tag以后,git数据模型如下:

4

修改根目录下init.rb文件提交后的git数据模型:

5

可以看到,每次commit都会产生一个新的tree
最后的git数据模型如下图所示,包含了16个不可改变的object

6

 

 

参考资料:
Git internals

Git object 类型笔记

Git objectsgit的实际存储数据,是git repository的重要组成部分,也是不可改变的。所有的git objects都存储在Git Object Database。每个object都是压缩(使用Zlib)的,通过内容的SHA-1值和一个头可以访问(Each object is compressed (with Zlib) and referenced by the SHA-1 value of its contents plus a small header.)。

(1)The Blob
Git中的文件内容存储成blob(要注意是内容,不是文件。文件的名字和模式不存储在blob。因此如果两个文件内容相同,则只会存储一份blob):

1

 

2

(2)The Tree
Git中的文件夹对应为treeTree中含有这个tree包含的blobtree的名字,模式,类型和SHA等信息:

3

4

(3)The Commit
Commit非常简单,只是指向了一个tree,并且包含了作者,提交者,提交信息,和所有的直属parent commit

5

6

(4)The Tag
Tag为某个commit提供了一个永久的shorthand name,它包含object、类型、tagtag作者和tag信息:

7

参考资料:
Git internals

git remote 命令简介

git remote会列出所有的remote repository名字,详细信息可以通过git remote -v得到。

git remote add <remote-name> <remote-path>可以添加一个remote repository,并且指定名字为<remote-name>。举例如下:

git remote add mary ../marys-repo

git fetch <remote-name>则是下载remote repository,但是不会merge

git merge <remote-name>/<branch-name>则是把<remote-name>/<branch-name>所指定的branch merge到当前的branch。举例如下:

git merge mary/master

git push <remote-name> <branch-name>是把本地一个branch上传到<remote-name>所指定的remote repository。举例如下:

git push mary dummy

git push <remote-name> <tag-name>则是上传指定的tag

git branch -r列出所有remote branch

git reset简介

git reset把当前branchHEAD恢复到之前某个snapshot。举例如下:

假设当前repository分三次添加abc文件:

[root@localhost test_git]# git log --oneline
e5b4692 Add c
be89e2d Add b
80c615e Add a

执行git reset --hard HEAD~1命令,HEAD~1表示当前HEAD之前的第一个commit

[root@localhost test_git]# git reset --hard HEAD~1
HEAD is now at be89e2d Add b
[root@localhost test_git]# git status
On branch master
nothing to commit, working directory clean
[root@localhost test_git]# git log --oneline
be89e2d Add b
80c615e Add a
[root@localhost test_git]# ls
a  b

可以看到git log中已经找不到添加c文件的log。而c文件也不存在了。

如果执行git reset --mixed HEAD~1命令,则虽然repository已经回滚到HEAD之前的第一个commit,但c文件还会存在:

[root@localhost test_git]# git reset --mixed HEAD~1
[root@localhost test_git]# git log --oneline
be89e2d Add b
80c615e Add a
[root@localhost test_git]# ls
a  b  c

恢复之前HEAD状态,可以利用git reflog找到相应的commit,然后创建一个新的branch,最后mergemaster:

[root@localhost test_git]# git reflog
be89e2d HEAD@{0}: reset: moving to HEAD~1
deb862b HEAD@{1}: commit: Add c
be89e2d HEAD@{2}: reset: moving to HEAD~1
e5b4692 HEAD@{3}: commit: Add c
be89e2d HEAD@{4}: commit: Add b
80c615e HEAD@{5}: commit (initial): Add a
[root@localhost test_git]# git checkout deb862b
Note: checking out 'deb862b'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at deb862b... Add c
[root@localhost test_git]# git log --oneline
deb862b Add c
be89e2d Add b
80c615e Add a
[root@localhost test_git]# git branch
* (HEAD detached at deb862b)
  master
[root@localhost test_git]# git checkout -b temp
Switched to a new branch 'temp'
[root@localhost test_git]# git branch
  master
* temp
[root@localhost test_git]# git checkout master
Switched to branch 'master'
[root@localhost test_git]# git merge temp
Updating be89e2d..deb862b
Fast-forward
 c | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 c
 [root@localhost test_git]# ls
a  b  c

Git rebase简介

假设当前git repository的情况是这样的:

5-3

git rebase <new-base>命令可以把当前branchcommit ID移到<new-base> branch的后面。执行下面两条命令:

git checkout about
git rebase master

git repository变为:

5-4

 

可以看到,同“3-way merge”相比(参考:Git branch简介),不用产生一个新的commit ID

git rebase -i <new-base>是交互式地进行rebase操作:可以对每个commit进行操作。举例如下:

git rebase -i master

执行完以后,会打开一个文本编辑器,列出所有需要操作的commit。修改如下:

pick 5cf316e Add empty page in about section
squash 964e013 Add contents to about page
pick 89db9ab Add HTML page for personal bio
squash 2bda8e5 Add empty HTML page for Mary's bio
pick 915466f Add link to about section in home page

前两个commit会合并成一个commit,接下来两个commit会合并成一个commit,最后一个commit保持不变。但是新生成的3commit都会有新的commit ID。这表明不仅仅是合并commit这么简单,而是git repositoryhistory完全被改写了。如下图所示:

5-5

 

另外,git rebase -i <new-base>还可以改写某个snapshot。举例如下:

git rebase -i master

然后edit中间的commit

pick 58dec2a Create the about page
edit 6ac8a9f Begin creating bio pages
pick 51c958c Add link to about section in home page

git处理到第2commit时,会停下来做一下“amending”:

5-6

处理完后,运行下面命令,提交commit

git add about/mary.html
git status
git commit --amend

--amend告诉git使用staged snapshot替代存在的commit而不是新创建一个commit
接下来继续rebase

git rebase --continue

如果rebase操作中间想放弃这次操作,可以使用“git rebase --abort”操作。

 

Git branch简介

git branch命令列出repository中所有的branch

[root@localhost git_repo]# git branch
* master

3-1

git branch <branch-name>会从当前working directoryfork出一个新的branch

[root@localhost git_repo]# git branch crazy

git checkout <branch-name>会切换到指定branchworking directory

[root@localhost git_repo]# git checkout crazy

3-3

Fast-forwarding merge:把fork出来的branch merge回原branch时,如果原branchfork出来的branch没有分叉,也即还在fork出来的branchrevision history里,则直接让原branchHEAD指向现在fork出来的branchsnapshot即可。如下图所示:

3-8

3-10

3-11

fast-forwarding merge相对应的是3-way merge:两个branch之间存在着分叉,这时mergebranch需要产生一个新的commit

4-1

参考资料:
Branches, Part I
Branches, Part II

Git中取消操作的方法

使用git revert命令取消已经committed的操作。举例如下:

[root@localhost git_repo]# git log --oneline
4a95041 Add a crazzzy experiment
5f08b5f Add navigation links
7f9fa70 Create blue and orange pages
7807520 Commit the first version of index.html.

如果想取消最后一次commitcommit ID4a95041),使用git revert 4a95041命令:

[root@localhost git_repo]# git revert 4a95041
[master 0b959a0] Revert "Add a crazzzy experiment"
 Committer: root <root@localhost.localdomain>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:

    git config --global --edit

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 1 file changed, 14 deletions(-)
 delete mode 100644 crazy.html
[root@localhost git_repo]# git log --oneline
0b959a0 Revert "Add a crazzzy experiment"
4a95041 Add a crazzzy experiment
5f08b5f Add navigation links
7f9fa70 Create blue and orange pages
7807520 Commit the first version of index.html.

现在第三次和第五次commit代表相同的snapshot。并且第四次commit还在revision history中,以后也可以恢复到第四次commit的内容。要注意,git revert命令使用的commit ID是要取消操作的commit ID,不是要“回滚”到的commit ID

取消还没committed的操作分以下两种情况:

(1)Tracked文件:git reset --hard命令会把所有tracked文件恢复到最近一次committed状态。加上--hard选项会真正更新文件,否则只是unstage文件,但文件的内容还是变化了。

(2)Untracked文件:git clean -f会删除所有untracked文件。

git reset取消working directorystaged snapshot的操作,而git revert是取消committed snapshots的操作。如下图所示:

2-5

参考资料:
Undoing Changes