乐者为王

Do one thing, and do it well.

FreeMind在Windows Server 2008中不能运行的问题

在Windows Server 2008下安装FreeMind后不能运行(0.8.1和0.9.0-RC4均是如此),使用的JRE是1.6.0_13。网上有的解决方法是在环境变量中添加jre\bin的路径。但是我不想这样做,想试试别的方法。

后来,从FreeMind的bug2750047中得到了启示,将javaw.exe拷贝到FreeMind的安装目录下就可以打开了。不过导致这个问题的原因目前还不清楚,因为在System32目录下确实有javaw.exe这个文件存在。不知道是不是因为安装的是64位版本的缘故。

允许客户端远程连接Lunarpages上的MySQL数据库

Lunarpages虚拟主机上的MySQL服务默认仅有本机能访问。只有在cPanel中向某IP地址或地址段或者所有地址开放访问权限后,才可以从外部用客户端连接数据库。

如果想允许任何主机的访问,直接在Host处填写百分号%,然后Add Host即可。如果只想特定主机访问,就输入客户端机器的IP地址。

lunarpages-mysql-remote

客户端远程连接时使用的地址就是虚拟空间的地址,可以通过ping域名得到。

Git笔记之rebase --onto

有的时候,可能需要修改某个已提交commit。如果是修改最近提交的commit,可以使用git commit --amend命令;如果是修改更早提交的commit,可以使用git rebase -i HEAD~n。不过这个命令有个缺陷,就是不能修改最早提交的那个commit。假设有如下提交历史:

1
C1--C2--C3--C4

要修改C4可以使用git commit --amend;要修改C2、C3或C4可以使用git rebase -i HEAD~n;但是如果要修改C1呢?这就需要rebase --onto出场了。下面就来实例讲解如何使用rebase --onto命令。

因为要修改C1这个commit,所以先在它之上创建临时分支tb:

1
git checkout -b tb C1

然后就可以在tb分支上做想要的修改,改完之后用下面的命令提交更改的内容:

1
git commit -a --amend

这时查看tb分支的提交历史,可以发现SHA1值已经发生了变化(master分支的SHA1值仍然不变):

1
C1'

接着可以把修改后的内容和master分支合并:

1
git rebase --onto tb C1 master

表示把master分支上从C1之后的所有commit重新apply到tb分支最新的commit之后。

这里有两点要注意:一个是C1处的开闭问题,rebase --onto的机制是左开右闭,也就是说上述命令只会apply三个提交C2、C3和C4;第二个是rebase --onto之后tb分支的提交历史没有改变,还是只有一个提交C1’,当前分支也切换到了master,并且所有commit的SHA1值都发生了改变。

1
C1'--C2'--C3'--C4'

最后就是正常的rebase --continue流程了。

Git笔记之分割提交

在rebase命令的交互模式下,你可以对历史提交中的任意提交进行分割操作,即把某个提交分割成多个提交。具体做法如下:

  1. 使用git rebase -i <commit>^开启rebase的交互模式,这里的<commit>是你想去分割的那个提交;
  2. 用动作edit标记你想分割的提交;
  3. 回到编辑提交的界面后,执行git reset HEAD^重置索引内容,使HEAD指向上个提交,把要分割的提交中的内容释放回工作目录;
  4. 现在你可以添加、修改或删除工作目录中的文件了,然后使用add -p和commit提交你想包含的任何内容;
  5. 重复第4步创建多个提交;
  6. 分割完成后使用git rebase --continue继续后续的工作。

至此,提交就被分割成功了。

Git笔记之branch,merge和rebase

1
2
3
4
5
6
7
8
git branch  # 列出所有分支以及当前在哪个分支上
git branch <branch>  # 建立分支
git branch -m <oldbranch> <newbranch>  # 修改分支的名字
git checkout <branch>  # 切换分支
git checkout -b <branch> <commit>  # 新建分支并切换过去
git branch -d <branch>  # 刪除分支
git merge <branch>  # 合并分支到当前分支上
git rebase <branch>  # 将提交迁移到上游分支

在merge/rebase的过程中,也许会出现冲突。在这种情况,Git会停止merge/rebase并让你去解决冲突,冲突内容以如下形式存在:

1
2
3
4
5
<<<<<<< HEAD
Here is the original change.
=======
Here is the modified chagne.
>>>>>>>

<<<<<<<下面的是当前版本的内容;=======和>>>>>>>之间的则是分支里与之对应的有冲突的内容。修复冲突要做的就是把<<<<<<< HEAD和>>>>>>>之间的内容改成我们想要的。在解决完冲突后,用git add命令去更新这些内容,如果是rebase,那么你无需执行git commit,只要执行git rebase --continue命令即可,这样Git会继续apply余下的补丁。

rebase的做法是先将HEAD指向目标分支的最新commit,这时HEAD的内容变为目标分支最新commit的SHA1值,然后将当前分支的commit,一个个重新apply到目标分支上,完成后再将HEAD指向新的commit。例如,当前分支是master,然后执行git rebase dev,就会把两个分支的共同祖先的commit之后的所有master的commit记录,重新在dev分支上再commit一遍。

git-rebase

fast-forward在Git中是一种merge术语,当dev分支是从master分支的最新commit分出来的时候,那么如果master要把dev分支merge进来,由于dev的parent commit是master的最新commit,所以这两个分支的合并不会有任何冲突,实际上的动作只是把master的HEAD指向dev的最新commit而已。线图上来看两个分支根本是同一条线。

git-merge-ff

Git笔记之tag

git tag的主要作用是给某个commit起一个好记的名字。这里列举了一些常用的tag命令:

1
2
3
4
git tag  # 显示所有标签
git tag v1.1.0  # 轻量级标签
git tag -a v1.1.0 -m "Release v1.1.0"  # 带注释的标签
git tag -d v1.1.0  # 删除特定标签

如果想给某个commit添加标签,可以使用如下命令:

1
git tag -a v1.1.0 <commit>

查看指定tag的信息可以用:

1
git show v1.1.0

要筛选同类标签的话,可以使用:

1
git tag -l 'v1.1.*'

它会列出前缀为v1.1.的所有标签。

有了标签要在团队之间分享怎么办?可以使用下面的命令把标签推送到远程仓库中:

1
2
git push origin v1.1.0  # 推送指定标签
git push origin --tags  # 推送所有标签

Git笔记之status

git status命令会显示当前项目状态的一个简单总结:

  • 当Git提示说“Untracked files”表示新增加的文件还没有被纳入到Git版本控制系统的追踪;
  • 如果提示说“Changed but not updated”表示在工作目录下做的修改还没有被添加到索引文件中;
  • 如果你看到提示说“Changes to be committed”则表示发现了你已经添加到索引文件里,但尚未提交的内容。

当然你也有可能喜欢短小的输出提示,那么可以使用-s选项:

1
git status -s
  • 它会用??表示“Untracked files”的文件;
  • 用红色的M表示“Changed but not updated”的文件;
  • 用绿色的M表示“Changes to be committed”;
  • 用绿色的A表示新增加但“Changes to be committed”的文件。

Git笔记之diff

今天,我们重点来探讨一下git diff的用法。

我们知道在Git提交环节存在三大部分:工作目录、索引文件、仓库。每当你对代码进行了修改,工作目录的状态就发生了改变。索引文件是连接工作目录和仓库的桥梁,每次当我们使用git add命令后,索引文件的内容就改变了,变得和工作目录同步。仓库是提交环节的最后阶段,只有在我们使用git commit命令将索引文件中的内容提交后,我们的代码才真正地进入了仓库。

git diff就是用来比较提交环节三大部分的差别。其中,纯粹的git diff是查看工作目录与索引文件之间的差别;git diff –cached是查看索引文件和仓库之间的差别;git diff HEAD则是查看工作目录和仓库之间的差别。

下图是三种查看方式的说明:

git-diff

git diff会输出全部的差别内容,但有时我们只想看看修改的内容的汇总,这时就可以使用--stat选项。这里是它的使用实例:

1
2
3
git diff --stat
git diff --cached --stat
git diff HEAD --stat

如果你想查看其它分支与当前分支的差别,只要运行以下命令即可:

1
git diff <otherbranch>

你也可以加上路径限定符,来比较某一个文件或目录:

1
git diff <otherbranch> <filename>

Git笔记之log

最简单的查看开发日志的命令是git log。如果你觉得git log给出的信息太单薄,那么可以使用git log -p,它不但会给出非常详细的开发日志,而且还会显示每次提交实际修改的内容。

git log支持很多的参数,可以将这些参数结合起来使用。下面是经常使用的一些参数:

1
2
3
4
5
6
7
-–name-only  # 只显示变更文件的名称
-–oneline    # 将提交信息压缩到一行显示
-–graph      # 显示所有提交的依赖树
-–reverse    # 按照逆序显示提交记录(最先提交的在最前面)
-–since      # 显示某个日期之后发生的提交
-–until      # 显示某个日期之前发生的提交
--decorate   # 显示每个commit的引用

如果你曾经与很多小伙伴工作在同一个分支上,也许会有这样的经历,master分支上的大量合并同步到你当前的分支。这使得我们很难分辨哪些变更是发生在master分支,哪些变更是发生在当前分支,且尚未合并到master分支。可以使用git log --no-merges master..查看尚未合并的变更。其中--no-merges选项表示着只显示没有合并到任何分支的变更,master..选项表示只显示没有合并到master分支的变更。

如果想查看文件中指定位置的变更怎么办?可以使用以下命令:

1
git log -L 1,1:<path>  # -L选项告诉Git只要输出指定文件中指定行的变更日志。

你还可以通过如下命令来定位具体的历史记录:

1
2
3
git log v3..v7                 # 显示v3之后直至v7的所有历史记录
git log v3..                   # 显示所有v3之后的历史记录
git log -–since="2 weeks ago"  # 显示2周前到现在的所有历史记录

如果这些都不够好用的话,还有一个--pretty选项,可以用来创建高级的自定义输出。譬如,你可以使用--pretty=raw查看日志的原始信息。

Git笔记之stash

在工作中,经常会碰到在修改代码以支持新功能时,发现线上版本出现问题需要在本地查错。因为还在进行中,所以并不想将半成品的代码提交,后面再来修改。这样就需要临时保存修改的文件,然后取出线上版本到工作目录。这个问题的解决之道就是使用git stash命令,它会暂存你的当前工作,这样以后随时可以再来修改:

1
git stash

现在,工作目录变得干净,可以安全地做些别的事情了。

要查看暂存的修改可以使用以下命令:

1
git stash list

稍后,在排除掉线上版本的错误后,你就可以取回所有暂存的修改:

1
git stash pop

现在让我们在脑中想象一个场景:在排除线上版本错误后,没有立即取回暂存的修改,而是做了其它的一些的变更,然后想把暂存的修改并入进来以完成工作。如果两次修改的代码没有冲突,那么事情完美结束;如果后修改的代码和暂存的修改有冲突,那么就会得到Merge conflict的警告。Git没有提供强制pop的功能,所以我们需要一些技巧来解决:

1
git stash show -p | git apply && git stash drop

git stash的其它一些可用选项如下所示:

1
2
3
4
git stash pop --index        # 不仅恢复工作目录,还恢复索引
git stash save "stash name"  # 使用save可以给暂存的修改添加名字
git stash save --keep-index  # 仅仅暂存未索引的文件
git stash clear              # 删除所有暂存的修改