## 2010年4月27日星期二

### Macport remove inactive ports

You can use this to remove inactive ports:
sudo port uninstall inactive

You will gain additional space by removing downloaded distfiles with:
sudo port clean --all installed

But there is no way to find orphaned ports, as MacPorts does not track
if ports are installed as dependency or by request. But there is the
tool port_cutleaves which allows to remove possible no longer needed ports.

sudo port install port_cutleaves
sudo port_cutleaves

sudo port selfupdate

sudo port -u upgrade --enforce-variants outdated +universal

### 一个 Ruby Rails 程序员在 Linux 下的工作环境

Awesome 在 LinuxTOY 上已经有文章介绍过了，我也是看了那篇文章才开始用它的，感谢那篇文章的作者。

Vim

Vim 开发 Rails 很方便，不太习惯现在 Eclipse、Netbeans 那些大而全的 IDE，它们有很多的优点值得借鉴，不过基本而言它们的启动速度都比较慢，运行后的反应速度也慢。下面是一些我用的 plugin：

• bufexplorer.vim - buffer 切换，console 下面常用

• lookupfile.vim - 找文件，很不错

• matchit.vim - 匹配成对的语句或符号，很有用

• mru.vim - 最常用文件列表，经常用

• NERD_commenter.vim - 快捷来加删 comment，不错

• project.vim - 基本我没用

• rails.vim - 开发 Rails 需要，但大部分好像我都不怎么用，恩，应该再看看它的帮助

• SimpleFold.vim - 它的折叠方法和 Vim 里面自带的那个语法文件不太一样，我个人觉得不错

• snippetsEmu.vim - 缩写代码自动生成，很不错，好用，但是自带的 Rails，Html 的少了点，需要自己再补充一些

• supertab.vim - 好用，常用

• surround.vim - 好用，常用

• taglist.vim - 不怎么用

• tailminusf.vim - 不怎么用

Xterm 或 Urxvt + Screen

Screen 是个好东西，通常我写一个 config 文件放在正在开发的 Rails 应用的目录下，然后 screen -c xxx.config  chdir some_workspace defutf8 on screen -t server 0 select 0 exec ruby script/server -u --debug screen -t console 1 exec ruby script/console screen -t log 2 exec tail -f log/development.log screen -t fastri 3 exec fastri-server fastri-server screen -t mysql 4 exec mysql mysql -uname -ppassword screen -t terminal

loop_qri.sh

! /bin/bashfunction selectmethod(){               select method in ${keywords} do if [[ "$REPLY" =~ ^[1-9][0-9]* ]]               then                       history -s "$method" history -w ~/.loopqrihistory echo"=============================================================================================" qri${method}                       echo"============================================================================================="                 haveselect=1                       break               else                       keywords="$REPLY" have_select=0 break fi done}history -r ~/.loopqrihistoryread -e -p "Please input some keywords of method:" keywordshaveselect=0while truedo case "$keywords" in                               -stop)                                               break                                               ;;                               -history)                                               history                                               ;;                               *)                                               COLUMNS=20                                               PS3="Choice a method or input other keywords: "                                               if [ $haveselect -eq 0 ] then matchresult=qri${keywords}                                         fi                                               if [[ "$matchresult" =~ "Multiple choices" ]] then keywords=echo "$match_result" | sed /--/d  | sed '/,/ s/,/ /g'                                                       echo"============================================================================================="                                                       selectmethod                                               else                                                       echo"============================================================================================="                                                 qri ${keywords} history -s "$keywords"                                                       history -w ~/.loopqrihistory                                                 haveselect=0                                                       read -e  -p "Please input some keywords of method:" keywords                                               fi               esacdone

Firefox + Firebug

Firefox 是个好东西，就是感觉它没有 Opera 快，尤其是打开很多 tab 以后不但慢而且不稳定，所以就只用它和 Firebug 来调试网页了。

Opera

Pidgin

MSN、QQ 都能用了，文字信息交流基本就够我用了。

Git

Xmodmap

Awesome

require 'rubygems'require 'awesomer'xmodmap ~/.Xmodmap注意这里不是单引号，而是 tab 上面那个键Awesomer.contact do |a|   a.tag_view 1a.spawn :xterm   sleep 3               a.clienttoggletag 3               a.clienttoggletag 4a.spawn :gvim   sleep 3               a.clienttoggletag 2               a.clienttoggletag 5a.tag_view 2a.spawn :firefox   sleep 16               a.clienttoggletag 3               a.clienttoggletag 6a.tag_view 9   a.spawn :opera   sleep 20a.tag_view 5end

### Changing Fonts in Text Mode

LaTeX has numerous commands for changing the typestyle.
The most useful of these is
\emph{text}
which emphasizes some piece of text, setting it
usually in an italic font (unless the surrounding
text is already italicized). Thus for example, the text

is obtained by typing

The basic results and techniques of \emph{Calculus}were discovered and developed by \emph{Newton}and \emph{Leibniz}, though many of the basic ideascan be traced to earlier work of \emph{Cavalieri},\emph{Fermat}, \emph{Barrow} and others.

Another useful font-changing command is
\textbf{text},
which typesets the specified portion of text in boldface.

A font family or typeface in LaTeX consists of a
collection of related fonts characterized by size, shape
and series. The font families available in LaTeX include
roman, sans serif and typewriter:

The sizes of fonts used in LaTeX are can be determined
and changed by means of the control sequences
\tiny,
\scriptsize,
\footnotesize,
\small,
\normalsize,
\large,

\Large,
\LARGE,
\huge and
\HUGE:

The shape of a font can be upright,
italic, slanted or small caps:

The series of a font can be medium (the default) or
boldface:

If the necessary fonts are available, one can combine changes to
the size, shape and series of a font, for example producing
boldface slanted text by typing
\textbf{\textsl{boldface slanted text}}.

There are in LaTeX font declarations corresponding to the
the font-changing commands described above. When included in the
LaTeX input such declarations determine the type-style of the
subsequent text (till the next font declaration or the end
of the current group' delimited by braces
or by appropriate \begin and \end
commands). Here is a list of font-changing commands and
declarations in text mode:

Command   Declaration\textrm   \rmfamily   Roman family\textsf   \sffamily   Sans serif family\texttt   \ttfamily   Typewriter family\textup   \upshape    Upright shape\textit   \itshape    Italic shape\textsl   \slshape    Slanted shape\textsc   \scshape    Small caps shape\textmd   \mdseries   Medium series\textbf   \bfseries   Boldface series

### XEmacs is Dead. Long Live XEmacs!

XEmacs is Dead. Long Live XEmacs!

 "We're going to get lynched, aren't we?" — Phouchg

And you thought I'd given up on controversial blogs. Hah!

Preamble

This must be said: Jamie Zawinski is a hero. A living legend. A major powerhouse programmer who, among his many other accomplishments, wrote the original Netscape Navigator and the original XEmacs. A guy who can use the term "downward funargs" and then glare at you just daring you to ask him to explain it, you cretin. A dude with arguably the best cat-picture blog ever created.

I've never met him, but I've been in awe of his work since 1993-ish, a time when I was still wearing programming diapers and needing them changed about every 3 hours.

Let's see... that would be 15 years ago. I've been slaving away to become a better programmer for fifteen years, and I'm still not as good — nowhere near as good, mind you — as he was then. I still marvel at his work, and his shocking writing style, when I'm grubbing around in the guts of the Emacs-Lisp byte-compiler.

It makes you wonder how many of him there are out there. You know, programmers at that level. He can't be the only one. What do you suppose they're all working on? Or do they all eventually make 25th level and opt for divine ascension?

In any case, I'm sad that I have to write the obit on one of his greater achievements. Sorry, man. Keep up the cat blog.

Forking XEmacs

I have to include a teeny history lesson. Bear with me. It's short.

XEmacs was a fork of the GNU Emacs codebase, created about 17 years ago by a famous-ish startup called Lucid Inc., which, alas, went Tango Uniform circa 1994. As far as I know, their two big software legacies still extant are a Lisp environment now sold by LispWorks, and XEmacs.

I'd also count among their legacies an absolutely outstanding collection of software essays called Patterns of Software, by Lucid's founder, Richard P. Gabriel. I go back and re-read them every year or so. They're that good.

Back when XEmacs was forked, there were some fireworks. Nothing we haven't seen many times before or since. Software as usual. But there was a Great Schism. Nowadays it's more like competing football teams. Tempers have cooled. At least, I think they have.

As for the whole sordid history of the FSF-Emacs/XEmacs schism, you can read about it online. I'm sure it was a difficult decision to make. There are pros and cons to forking a huge open-source project. But I think it was the right decision at the time, just as decomissioning it is the right decision today, seventeen years later.

XEmacs dragged Emacs kicking and screaming into the modern era. Among many other things, XEmacs introduced GUI widgets, inline images, colors in terminal sessions, variable-size fonts, and internationalization. It also brought a host of technical innovations under the hood. And XEmacs has always shipped with a great many more packages than GNU Emacs, making it more of a turnkey solution for new users.

XEmacs was clearly an important force helping to motivate the evolution of GNU Emacs during the mid- to late-1990s. GNU Emacs was always playing catch-up, and the dev team led by RMS (an even more legendary hacker-hero) complained that XEmacs wasn't really playing on a level field. The observation was correct, since XEmacs was using a Bazaar-style development model, and could move faster as a direct consequence.

A lot of people were switching over to XEmacs by the mid-1990s: the fancy widgets and pretty colors attracted GNU Emacs users like moths to a bug-zapper.

Problem was, it could actually zap you.

The downside of the Bazaar

I personally tried to use XEmacs many times over a period of many years. I was jealous of its features.

However, I never managed to use XEmacs for very long, because it crashed a lot. I tried it on every platform I used between ~1996 and 2001, including HP/UX, SunOS, Solaris, Ultrix, Linux, Windows NT and Windows XP. XEmacs would never run for more than about a day under moderate use without crashing.

I've argued previously that one of the most important survival traits of a software system is that it should never reboot. Emacs and XEmacs are at the leading edge of living software systems, but XEmacs has never been able to take advantage of this property because even though it can live virtually forever, it's always tripping and falling down manholes.

Clumsy XEmacs. Clumsy!

I assume its propensity for inopportune heart attacks is a function of several things, including (a) old-school development without unit tests, (b) the need to port it to a gazillion platforms, including many that nobody actually uses, (c) a culture of rapid addition of new features. There are probably other factors as well.

I'm just speculating though. All I know is that it's always been very, very crashy. It doesn't actually matter what the reasons are, since there's no excuse for it.

Interestingly, most XEmacs users I've talked to say they don't notice the crashing. I'm sure this is because it's all relative. XEmacs doesn't crash any more often than Firefox, for instance. Probably less often. When Firefox crashes I make a joke about it and restart it, because the crashing rarely has an impact. It even restores your state properly most of the time, so it's just a minor blip, an almost trivial inconvenience, so long as whatever text field you happen to be editing has an auto-save feature. And most of the good ones do.

XEmacs may crash even less than Eclipse and IntelliJ. Crashing editors usually aren't a big problem. Programmers all learn the hard way to save their buffers frequently. For me, saving is like punctuation; I save whenever my typing pauses, out of reflex. Doesn't matter whether it's Emacs or NeoOffice or GMail or... do I use any other apps? Oh yeah, or the Gimp. When I pause, I save, and if you're a programmer I bet you do too. So occasional crashes may seem OK.

Another reason the crashes aren't called out more often is that most Emacs and XEmacs users are at best casual users. They open up an {X}Emacs session whenever they need to edit a file, and close it when they're done. It's just Notepad with colors and multi-level Undo.

If your average session length is shorter than the editor's MTBF, then yeah, you're not going to notice much crashing.

In contrast, your more... ah, seasoned (read: fanatical) Emacs users gradually come to live in it. Anything you can't do from within Emacs is an annoyance. It's like having to drive to a government building downtown to take care of some random paperwork they should have been offering as an online service a decade ago. You can live with it, but you're annoyed.

Even Firefox, the other big place I live, really wants to be Emacs. Tabs don't scale. Tabbed browsing was revolutionary in the same way adding more tellers to a bank was revolutionary: it's, like, 4x better. w00t. Emacs offers the unique ability to manage its open buffers in another first-class buffer, as a list. Imagine what your filesystem life would be like if the only view of a directory was one tab per file. Go to your pictures directory and watch it start vomiting tabs out like it tried to swallow a box of chiclets. Fun!

I feel sad when I see Eclipse users with fifty open tabs, an army of helpful termites eating away at their screen real-estate and their time.

I have a feeling I've veered off course somewhere... where was I? Oh yeah. Crashing.

So XEmacs has never been a particularly good tool for serious Emacs users because even though it's written in C, it crashes like a mature C++ application. You know the drill: major faceplants, all the fugging time.

Your ability to become an inhabitant of Emacs is gated by how stable it is. GNU Emacs has always been famously stable. Sure, the releases happen less frequently than presidential inaugurations. Sure, for a long time it always lacked some XEmacs feature or other. But it's really, really stable. Its MTBF is measurable in weeks (or even months, depending on what you're doing with it) as opposed to hours or days.

Emacs, like Firefox, can be configured to back up your state periodically, so that in theory it can recover after a crash. That's part of the problem: you didn't actually have to configure Firefox to get that behavior. It does it automatically. And to be honest, I've never had much luck with the Emacs save-state facilities. I'm a pretty competent elisp hacker these days, but the desktop.el has never worked reliably for me. I could probably get it to work, but I've always found it easier to write specialized startup "scripts" (lisp functions) that load up particular favorite configurations.

If I can't get desktop-save working, I'd guess that fewer than 1/10th of 1 percent of Emacs users use that feature. So crashes blow everything away.

If the state isn't being auto-saved, the next best thing is for it not to crash.

XEmacs never got that right.

Don't get me wrong...

I just realized I'm going to get screamed at by people who think I'm just an XEmacs-hater slash GNU-fanboy.

Make no mistake: I'm a fan of XEmacs. I think it was a great (or at least, necessary) idea in 1991. I think the execution, aside from the stability issue, was top-notch. I think it had a good architecture, by and large, at least within the rather severe constraints imposed by Emacs Lisp. I think it spurred competition in a healthy way.

I think the XEmacs development team, over the years, has consisted of engineers who are ALL better than I am, with no exceptions. And I even like certain aspects of the interface better, even today now that GNU Emacs has caught and surpassed XEmacs in features. For instance, I like the XEmacs "apropos" system better.

If you're going to scream at me for irrational reasons, it really ought to be for the right irrational reasons. Legitimate dumb reasons for screaming at me include: you're lazy and don't want to learn anything new; you invested a lot of time in XEmacs and don't see why you should be forced to switch; you are a very slow reader, causing you to skip three out of every five words I write, resulting in your receipt of a random approximation of my blog content, with a high error bar; you're still mad about my OS X blog. All good bad reasons.

Heck, you could even scream for rational reasons. Perhaps you have a philosophical beef with the FSF or GPL3. Perhaps XEmacs still has some vestiges of feature support that do not yet exist in GNU Emacs, and you truly can't live without them. I would think you're being a teeny bit uptight, but I would respect your opinion.

Whatever you do, just don't yell at me for thinking I'm dissing XEmacs or taking some sort of religious stance. Far from it. I just want a unified Emacs-o-cratic party.

XEmacs vs. GNU Emacs today

GNU Emacs pulled into the lead in, oh... I'd say somewhere around maybe 2002? 2003? I wasn't really keeping track, but one day I noticed Emacs had caught up.

Even today I maintain XEmacs/FSF-Emacs compatibility for my elisp files – some 50k lines of stuff I've written and maybe 400k lines of stuff I've pilfered from EmacsWiki, friends, and other sources. I still fire up XEmacs whenever I need to help someone get un-stuck, or to figure out whether some package I've written can be coerced to run, possibly in restricted-feature mode, under XEmacs.

For years I chose stability over features. And then one day GNU Emacs had... well, everything. Toolbars, widgets, inline images, variable fonts, internationalization, drag-and-drop in and out of the OS clipboard (even on Windows), multi-tty, and a long laundry-list of stuff I'd written off as XEmacs-only.

And it was still stable. Go figure.

I don't have the full feature-compatibility list. Does it even exist? You know, those tables that have little red X's if the Evil Competitor product is missing some feature your product offers, and little green checkmarks, and so on. We ought to make one of those. It would be useful to know what (if any) XEmacs features are preventing the last holdouts from migrating to FSF Emacs.

But for the past five years or so, just about every time an XEmacs user on a mailing list has mentioned a feature that's keeping them from switching, it's been solved.

If GNU Emacs isn't a perfect superset of XEmacs yet, I'm sure we could get it there if we had the big unified-platform carrot dangling in front of us. And I bet it's pretty close already.

Features and stability aside, XEmacs is looking pretty shabby in the performance department. Its font-lock support has never been very fast, and a few years back GNU Emacs took a giant leap forward. XEmacs can take 4 or 5 seconds or longer to fontify a medium-sized source file. Sure, it shows that big progress bar in the middle of the screen, so you know it's not dead, but when you're used to it being almost instantaneous, coming back to XEmacs is a real shocker.

And XEmacs has bugs. Man, it has a lot of bugs. I can't begin to tell you how many times I've had to work around some horrible XEmacs problem. It has bugs (e.g. in its fontification engine and cc-engine) that have been open for years, and they can be really painful to work around. I've had to take entire mode definitions and if-xemacs them, using an ancient version of the mode for XEmacs because nothing even remotely recent will run.

You may not notice the bugs, but as elisp developers, we feel the pain keenly.

Fundamental incompatibilities

As if issues with stability, performance and bugs weren't enough, XEmacs has yet another problem, which is that its APIs for dealing with UI elements (widgets and input events, but also including things like text properties, overlays, backgrounds and other in-buffer markup) are basically completely different from their GNU-Emacs counterparts. The two Emacsen share a great deal of common infrastructure at the Lisp level: they have mostly compatible APIs for dealing with files, buffers, windows, subprocesses, errors and signals, streams, timers, hooks and other primitives.

But their APIs range from mildly to completely different for keyboard and mouse handling, menus, scrollbars, foreground and background highlighting, dialogs, images, fonts, and just about everything else that interfaces with the window system.

The GUI and display code for any given package can be a significant fraction of the total effort, and it essentially has to be rewritten from scratch when porting from GNU Emacs to XEmacs or vice-versa. Unsurprisingly, many package authors just don't do it. The most famous example I can think of is James Clark's nxml-mode, which claims it'll never support XEmacs. I found that pretty shocking, since I thought it was basic Emacs etiquette to try to support XEmacs, and here James was cutting all ties, all public about it and everything. Wow.

But I totally understand, since I really don't want to rewrite all the display logic for my stuff either.

I'll be the first to admit: the API discrepancies are not XEmacs's fault. I can't see how they could be, given that for nearly all these features, XEmacs had them first.

For a developer trying to release a productivity package, it doesn't really matter whose fault it is. You target the platform that will have the most users. I don't know what XEmacs's market share is these days, but I'd be very surprised if it's more than 30%. That's a big number, but when you're an elisp hacker creating an open-source project in your limited spare time, that number can start looking awfully small. Teeny, even.

XEmacs should drop out of the race

At this point it's becoming painful to watch. GNU Emacs is getting all the superdelegates. That warmonger VIM is sitting back and laughing at us. But XEmacs just won't quit!

I'm sure there are a few old-timers out there who still care about the bad blood that originally existed between the two projects. To everyone else it's ancient history. As far as I can tell, there has been an atmosphere of polite (if subdued) cooperation between the two projects. Each of them has incorporated some compatibility fixes for the other, although it's still mostly up to package authors to do the heavy lifting of ensuring compatibility, especially for display code.

I haven't seen any XEmacs/GNU-Emacs flamewars in a long time, either. We're all just *Emacs users, keeping our community alive in the face of monster IDEs that vomit tabs, consume gigabytes of RAM, and attract robotic users who will probably never understand the critical importance of customizing and writing one's own tools.

When the Coke/Pepsi discussion comes up these days, it's usually an XEmacs user asking, in all seriousness, whether they should transition to GNU Emacs, and if so, would someone volunteer to help migrate their files and emulate their favorite behaviors.

Yes, someone will volunteer. I promise.

The dubious future of Emacs

I've got good news and bad news.

The good news is: Emacs is a revolutionary, almost indescribably QWAN-infused software system. Non-Emacs users and casual users simply can't appreciate how rich and rewarding it is, because they have nothing else to compare it to. There are other scriptable applications and systems out there — AppleScript, Firefox, things like that. They're fun and useful. But Emacs is self-hosting: writing things in it makes the environment itself more powerful. It's a feedback loop: a recursive, self-reinforcing, multiplicative effect that happens because you're enhancing the environment you're using to create enhancements.

When you write Emacs extensions, sometimes you're automating drudgery (always a good thing), sometimes you're writing new utilities or apps, and sometimes you're customizing the behavior of existing utilities. This isn't too much different from any well-designed scriptable environment. But unlike in other environments, sometimes you're improving your editing tools and/or your programming tools for Emacs itself. This notion of self-hosting software is something I've been wanting to blog more about, someday when I understand it better.

Eclipse and similar environments want to be self-hosting, but they're not, because Java is not self-hosting. In spite of Java's smattering of dynamic facilities, Java remains as fundamentally incapable of self-hosting as C++. Self-hosting only works if the code can "fold" on itself and become more powerful while making itself smaller and cleaner. I'm not really talking about macros here, even though that's probably the first thing you thought of. I'm thinking more along the lines of implementing JITs and supercompilers in the hosted runtime, rather than in the C++ or Java "hardware" substrate, which is where everyone puts them today.

I suspect (without proof) that in self-hosted environments, you can eventually cross a threshold where your performance gains from features implemented in the hosted environment outpace the gains from features in the substrate, because of this self-reinforcing effect: if code can make _itself_ faster and smarter, then it will be faster and smarter at making itself faster and smarter. In C++ and Java, making this jump to the self-reinforcing level is essentially intractable because, ironically, they have so many features (or feature omissions) for the sake of performance that they get in their own way.

To be sure, Emacs, the current crop of popular scripting languages, and other modestly self-hosting environments are all pretty far from achieving self-reinforcing performance. But Emacs has achieved it for productivity – at least, for the relatively small percentage of Emacs users who learn enough elisp to take advantage of it. There are just enough of us doing it to generate a steady supply of new elisp hackers, and the general-purpose artifacts we produce are usually enough to keep the current crop of casual users happy.

The bad news: the competition isn't the IDEs

I've argued that Emacs is in a special self-reinforcing software category. For productivity gains, that category can only be occupied by editors, by definition, and Emacs is currently way ahead of any competition in most respects. So most Emacs users have felt safe in the assumption that IDEs aren't going to replace Emacs.

Unfortunately, Emacs isn't immunized against obsolescence. It still needs to evolve, and evolve fast, if it's going to stay relevant. The same could be said of any piece of software, so this shouldn't be news. But it's particularly true for Emacs, because increasing numbers of programmers are being lured by the false productivity promises of IDEs.

They really are false promises: writing an Eclipse or IntelliJ (or God help you, Visual Studio) plugin is a monumental effort, so almost nobody does it. This means there's no community of building and customizing your own tools, which has long been the hallmark of great programmers. Moreover, the effort to create a plugin is high enough that people only do it for really significant applications, whereas in Emacs a "plugin" can be any size at all, from a single line of code up through enormous systems and frameworks.

Emacs has the same learning-curve benefit that HTML had: you can start simple and gradually work your way up, with no sudden step-functions in complexity. The IDEs start you off with monumental API guides, tutorials, boilerplate generators, and full-fledged manuals, at which point your brain switches off and you go over to see what's new on reddit. ("PLEASE UPMOD THIS PIC ITS FUNNY!")

And let's not even get into the Million Refactorings yet. It's a blog I've been working on for years, and may never finish, but at some point I'd like to try to show IDE users, probably through dozens or even hundreds of hands-on examples I've been collecting, that "refactoring" is an infinite spectrum of symbol manipulation, and they have, um, twelve of them. Maybe it's thirteen. Thirteen out of infinity – it's a start!

Programmers are being lured to IDEs, but the current crop of IDEs lacks the necessary elements to achieve self-hosting. So the only damage to Emacs (and to programmers in general) is that the bar is gradually going down: programmers are no longer being taught to create their own tools.

IDEs are draining users away, but it's not the classic fat-client IDEs that are ultimately going to kill Emacs. It's the browsers. They have all the power of a fat-client platform and all the flexibility of a dynamic system. I said earlier that Firefox wants to be Emacs. It should be obvious that Emacs also wants to be Firefox. Each has what the other lacks, and together they're pretty damn close to the ultimate software package.

If Emacs can't find a way to evolve into (or merge with) Firefox, then Firefox or some other extensible browser is going to eclipse Emacs. It's just a matter of time. This wouldn't be a bad thing, per se, but there's a good chance it would be done poorly, take forever, and wind up being less satisfying than if Emacs were to sprout browser-like facilities.

Emacs as a CLR

So Emacs needs to light a fire and hurry up and get a better rendering engine. Port to XUL, maybe? I don't know, but it's currently too limited in the application domains it can tackle. I realize this is a very hard problem to solve, but it needs to happen, or at some point a rendering engine will emerge with just enough editing power to drain the life from Emacs.

Emacs also needs to take a page from the JVM/CLR/Parrot efforts and treat itself as a VM (that's what it is, for all intents) and start offering first-class support for other languages. It's not that there's anything wrong with Lisp; the problem is X programmers. They only want to use X, so you have to offer a wide range of options for X. Emacs could be written in any language at all, take your pick, and it wouldn't be good enough.

RMS had this idea a long, long time ago (when he was making the rather controversial point that Tcl isn't a valid option for X), and it eventually led to Guile, which led more or less nowhere. Not surprising; it's a phenomenally difficult challenge. There are really only two VMs out there that have achieved even modest success with hosting multiple languages: the CLR and the JVM. CLR's winning that race, although it's happening in a dimension (Windows-land) that most of us don't inhabit. Parrot is... trying really hard. Actually, I should probably mention LLVM, which (like Parrot) was designed from the ground up for multi-language support, but took a lighter-weight approach. So let's call it four.

In any case, it's a small very group of VMs, and they still haven't quite figured out how to do it: how to get the languages to interoperate, how to get languages other than the first to perform decently, and so on.

This is clearly one of the hardest technical challenges facing our industry for the next 10 years, but it's also one of the most obviously necessary. And Emacs is going to have to play that game. I'm not talking about hacked-together process bridges like PyMacs or el4r, either — I mean first-class support and all that it entails.

I've mentioned the rendering engine and the multi-language support; the last major hurdle is concurrency. I don't know the answer here, either, but it needs an answer. Threads may be too difficult to support with the current architecture, but there are other options, and someone needs to start thinking hard about them. Editing is becoming a complicated business — too complicated for hand-rolling state machines.

Compete or die

So Emacs has some very serious changes ahead.

Let's face it: we're not going to see real change unless ALL the Emacs developers out there – today's crop of JWZs – band together to make it happen. But today we're divided. Two groups of brilliant C hackers working on separate, forked code bases? That's bad. Two groups of maniacal elisp hackers working on incompatible packages, or at best wasting time trying to achieve compatibility? Also bad.

Developers are starting to wake up and realize that the best "mainstream" extensible platform (which excludes Emacs, on account of the Lisp) is Firefox or any other non-dead browser (which excludes IE). Dynamic typing wins again, as it always will. Dynamic typing, property-based modeling and non-strict text protocols won the day for the web, and have resisted all incursions from heavyweight static replacements. And somehow the web keeps growing, against all the predictions and lamentations of the static camp, and it still works. And now the browsers are starting to sprout desktop-quality apps and productivity tools. It won't be long, I think, before the best Java development environment on the planet is written in JavaScript.

Emacs has to compete or die. If Firefox ever "tips" and achieves even a tenth of the out-of-the-box editing power of Emacs, not just for a specific application but for all web pages, widgets, text fields and system resources, Emacs is going to be toast. I may be the last rat on the ship, but I'm sure not going down with it; even _I_ will abandon Emacs if Firefox becomes a minimally acceptable extensible programmer's editor. This is a higher bar than you probably think, but it could happen.

We no longer need XEmacs to spur healthy competition. The competition is coming in hard from entirely new sources. What we need now is unity.

Then why not unify behind XEmacs?

I threw this in just in case you blew through the article, which I'd find perfectly understandable. To summarize, I've argued that XEmacs has a much lower market share, poorer performance, more bugs, much lower stability, and at this point probably fewer features than GNU Emacs. When you add it all up, it's the weaker candidate by a large margin.

Hence there's only one reasonable strategy: Hill, er, I mean XEmacs has to drop out of the race.

I'm really sorry about this. I'm a close personal friend of XEmacs, but I just can't endorse it anymore. I used to be a laissez-faire kinda guy, as long as you were using some flavor of Emacs. But at this point, if you're using XEmacs you're actively damaging not only your long-term productivity, but mine as well. So I'd like to ask you to think long and hard about switching. Soon.

If you're a local Emacs-Lisp guru, please offer your services to XEmacs users who would like to switch over. The more pain-free the migration is, the faster it will happen.

If you're a graphic artist, consider making a nice, tasteful "Euthanize XEmacs!" logo. Not that message, precisely, but something along those lines. Make sure it's tasteful. Perhaps "XEmacs is dead – long live XEmacs"? Yes, I think that would do nicely.

If you happen to know someone on the XEmacs development team, send them some chocolates, or movie tickets, or something. A thank-you, even. We should honor their service. But those guys are the most qualified on the planet to step in and start helping drive GNU Emacs forward, assuming the FSF team will have them. Emacs is in very bad shape indeed if they will not.

If you're a local system administrator, consider sudo rm -rf xemacs. Sorry, I mean consider politely asking your emacs-users mailing list if they might be willing to set a timeline for deprecating XEmacs, thereby starting the most massive flamewar in your company's history. Can't hurt!

If you're seeing red, and you skipped most of this article so you could comment on how amazingly lame this idea is, I recommend taking a little walk and getting some fresh air first.

If you're RMS, thank you for making Emacs and all that other stuff, and for keeping it free. Please be nice to those who wish to help. You're scary to the point of unapproachability, just 'cuz you're you.

XEmacs team, JWZ, and XEmacs package authors: thank you all for helping drive progress in the greatest piece of software of all time. I can only hope that someday I may have chops like that.

Now how about we turn this into the most famous reverse-fork in history?

## Ffmpeg/x264 (profile High, level 3.0) (latest versions of x264) ¶

We have successfully been using ffmpeg/libx264 with two pass encoding using the following commands:

  infile ="video.avi"  tmpfile="video_tmp.mp4"  outfile="video.mp4"  options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \	   -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \	   -me_method hex -subq 7 -trellis 1 -refs 5 -bf 3 \	   -flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16 \           -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\	   -qmax 51 -qdiff 4"  ffmpeg -y -i "$infile" -an -pass 1 -threads 2$options "$tmpfile" ffmpeg -y -i "$infile" -acodec libfaac -ar 44100 -ab 96k -pass 2 -threads 2 $options "$tmpfile"  qt-faststart "$tmpfile" "$outfile"

The last line 'qt-faststart' is optional. It doesn't hurt though and it even may save a little time on the server which is hosting the movie files.

Thanks to S0ma for the updated options.

## Ffmpeg/x264 (profile High, level 3.0) (older versions) ¶

Replace the options above with:

  options="-vcodec libx264 -b 512k -bf 3 -subq 6 -cmp 256 -refs 5 -qmin 10 \           -qmax 51 -qdiff 4 -coder 1 -loop 1 -me hex -me_range 16 -trellis 1 \           -flags +mv4 -flags2 +bpyramid+wpred+mixed_refs+brdo+8x8dct \           -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -g 250 \           -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71"

## Ffmpeg/x264 (profile Baseline, level 3.0) (iPhone) ¶

Replace the options above with:

  options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \	   -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \	   -me_method hex -subq 7 -trellis 1 -refs 5 -bf 0 \	   -flags2 +mixed_refs -coder 0 -me_range 16 \           -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\	   -qmax 51 -qdiff 4"

## Mencoder & mp4creator ¶

Thanks to Martin Bündgens for the following PHP script.

system("mencoder ". $file_input ." -o ".$file_output_raw ." -ovc x264 -x264encopts       bitrate=300:threads=auto:subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid:weight_b       -vf bmovl=0:0:mylogo.fifo,scale=". $nw .":".$nh .",harddup -oac faac -faacopts br=56:mpeg=4:object=2       -srate 44100 -ofps 24000/1001");system("mplayer ". $file_output_raw. " -dumpaudio -dumpfile ".$file_output_aac ."");system("mplayer ". $file_output_raw. " -dumpvideo -dumpfile ".$file_output_h264 ."");system("mp4creator -create=". $file_output_aac. " ".$file_output ."");system("mp4creator -create=". $file_output_h264. " -rate=23.976 ".$file_output ."");system("mp4creator -hint=1 ". $file_output ."");system("mp4creator -hint=2 ".$file_output ."");system("mp4creator -optimize ". $file_output .""); ## Telestream Episode Engine Pro 5 ¶ Files transcoded by a Telestream Episode Engine Pro 5 are reported to work. The files are H264/AAC in an MP4 container. They are compatible with both Flash and iPod. ## Encoding H264 on Tiger ¶ Here is a little wisdom snippet from challefredde: I'm using different tools but mostly this combination: On Mac OS X 10.4 Tiger: • Perian plugin installed (watch almost all videos in Quicktime) • Mpeg Streamclip from Squared 5 • x264 Quicktime codec. Encodes better h264 videos than Quicktime's built-in. • QTFastStart Video: 900 kbit/s, Audio: AAC, stereo 96 kbit/s, Res: 640x360 (widescreen) The video plays fine on iPod's. ### FFMPEG参数说明 ffmpeg命令行参数设定解说 ffmpeg参数设定解说 -bitexact 使用标准比特率 -vcodec xvid 使用xvid压缩 -s 320x240 指定分辨率 -r 29.97 桢速率（可以改，确认非标准桢率会导致音画不同步，所以只能设定为15或者29.97） 画面部分，选其一 -b <比特率> 指定压缩比特率，似乎ffmpeg是自动VBR的，指定了就大概是平均比特率，比如768，1500这样的就是原来默认项目中有的 -qscale <数值> 以<数值>质量为基础的VBR，取值0.01-255，约小质量越好 -qmin <数值> 设定最小质量，与-qmax（设定最大质量）共用，比如-qmin 10 -qmax 31 -sameq 使用和源同样的质量 声音部分 -acodec aac 设定声音编码 -ac <数值> 设定声道数，1就是单声道，2就是立体声，转换单声道的TVrip可以用1（节省一半容量），高品质的DVDrip就可以用2 -ar <采样率> 设定声音采样率，PSP只认24000 -ab <比特率> 设定声音比特率，前面-ac设为立体声时要以一半比特率来设置，比如192kbps的就设成96，转换君默认比特率都较小，要听到较高品质声音的话建议设到160kbps（80）以上 -vol <百分比> 设定音量，某些DVDrip的AC3轨音量极小，转换时可以用这个提高音量，比如200就是原来的2倍 这样，要得到一个高画质音质低容量的MP4的话，首先画面最好不要用固定比特率，而用VBR参数让程序自己去判断，而音质参数可以在原来的基础上提升一点，听起来要舒服很多，也不会太大（看情况调整） 1． 视频音频格式转换 Ffmpeg能使用任何支持的格式和协议作为输入： *比如你可以输入YUV文件：ffmpeg -i /tmp/test%d.Y /tmp/out.mpg 它将要使用如下文件： /tmp/test0.Y, /tmp/test0.U, /tmp/test0.V, /tmp/test1.Y, /tmp/test1.U, /tmp/test1.V,等等… *你能输入原始的YUV420P文件：ffmpeg -i /tmp/test.yuv /tmp/out.avi 原始的YUV420P文件包含原始的YUV极性，每帧以Y平面开始，跟随U和V平面，它们是Y平面水平垂直的一半分辨率 *你能输出原始的YUV420P文件 ffmpeg -i mydivx.avi -o hugefile.yuv *你能设置几个输入文件和输出文件 ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg 上面的命令行转换音频文件a.wav和原始的YUV 视频文件 a.yuv到mpeg文件a.mpeg *你也能同时转换音频和视频 ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2 上面的命令行转换a.wav的采样率到22050HZ并编码为mpeg音频 *你也能同时编码到几种格式并且在输入流和输出流之间建立映射 ffmpeg -i /tmp/a.wav -ab 64 /tmp/a.mp2 -ab 128 /tmp/b.mp2 -map 0:0 -map 0:0 上面的命令行转换一个64Kbits 的a.wav到128kbits的a.mp2 ‘-map file:index’在输出流的顺序上定义了那一路输入流是用于每一个输出流的， 转码解密的VOB: ffmpeg -i snatch_1.vob -f avi -vcodec mpeg4 -b 800 -g 300 -bf 2 -acodec mp3 -ab 128 snatch.avi 上面的命令行将vob的文件转化成avi文件，mpeg4的视频和mp3的音频。注意命令中使用了B帧，所以mpeg4流是divx5兼容的。GOP大小是300意味着29.97帧频下每10秒就有INTRA帧。该映射在音频语言的DVD转码时候尤其有用 2． Ffmpeg使用语法 ffmpeg [[options][-i' input_file]]... {[options] output_file}... 如果没有输入文件，那么视音频捕捉就会起作用。 作为通用的规则，选项一般用于下一个特定的文件。如果你给 –b 64选项，改选会设置下一个视频速率。对于原始输入文件，格式选项可能是需要的。 缺省情况下，ffmpeg试图尽可能的无损转换，采用与输入同样的音频视频参数来输出。 3．选项 a) 通用选项 -L license -h 帮助 -fromats 显示可用的格式，编解码的，协议的。。。 -f fmt 强迫采用格式fmt -I filename 输入文件 -y 覆盖输出文件 -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持 -title string 设置标题 -author string 设置作者 -copyright string 设置版权 -comment string 设置评论 -target type 设置目标文件类型(vcd,svcd,dvd) 所有的格式选项（比特率，编解码以及缓冲区大小）自动设置 ，只需要输入如下的就可以了： ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg -hq 激活高质量设置 -itsoffset offset 设置以秒为基准的时间偏移，该选项影响所有后面的输入文件。该偏移被加到输入文件的时戳，定义一个正偏移意味着相应的流被延迟了 offset秒。 [-]hh:mm:ss[.xxx]的格式也支持 b) 视频选项 -b bitrate 设置比特率，缺省200kb/s -r fps 设置帧频 缺省25 -s size 设置帧大小 格式为WXH 缺省160X128.下面的简写也可以直接使用： Sqcif 128X96 qcif 176X144 cif 252X288 4cif 704X576 -aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777 -croptop size 设置顶部切除带大小 像素单位 -cropbottom size –cropleft size –cropright size -padtop size 设置顶部补齐的大小 像素单位 -padbottom size –padleft size –padright size –padcolor color 设置补齐条颜色(hex,6个16进制的数，红:绿:兰排列，比如 000000代表黑色) -vn 不做视频记录 -bt tolerance 设置视频码率容忍度kbit/s -maxrate bitrate设置最大视频码率容忍度 -minrate bitreate 设置最小视频码率容忍度 -bufsize size 设置码率控制缓冲区大小 -vcodec codec 强制使用codec编解码方式。 如果用copy表示原始编解码数据必须被拷贝。 -sameq 使用同样视频质量作为源（VBR） -pass n 选择处理遍数（1或者2）。两遍编码非常有用。第一遍生成统计信息，第二遍生成精确的请求的码率 -passlogfile file 选择两遍的纪录文件名为file - c)高级视频选项 -g gop_size 设置图像组大小 -intra 仅适用帧内编码 -qscale q 使用固定的视频量化标度(VBR) -qmin q 最小视频量化标度(VBR) -qmax q 最大视频量化标度(VBR) -qdiff q 量化标度间最大偏差 (VBR) -qblur blur 视频量化标度柔化(VBR) -qcomp compression 视频量化标度压缩(VBR) -rc_init_cplx complexity 一遍编码的初始复杂度 -b_qfactor factor 在p和b帧间的qp因子 -i_qfactor factor 在p和i帧间的qp因子 -b_qoffset offset 在p和b帧间的qp偏差 -i_qoffset offset 在p和i帧间的qp偏差 -rc_eq equation 设置码率控制方程 默认tex^qComp -rc_override override 特定间隔下的速率控制重载 -me method 设置运动估计的方法 可用方法有 zero phods log x1 epzs(缺省) full -dct_algo algo 设置dct的算法 可用的有 0 FF_DCT_AUTO 缺省的DCT 1 FF_DCT_FASTINT 2 FF_DCT_INT 3 FF_DCT_MMX 4 FF_DCT_MLIB 5 FF_DCT_ALTIVEC -idct_algo algo 设置idct算法。可用的有 0 FF_IDCT_AUTO 缺省的IDCT 1 FF_IDCT_INT 2 FF_IDCT_SIMPLE 3 FF_IDCT_SIMPLEMMX 4 FF_IDCT_LIBMPEG2MMX 5 FF_IDCT_PS2 6 FF_IDCT_MLIB 7 FF_IDCT_ARM 8 FF_IDCT_ALTIVEC 9 FF_IDCT_SH4 10 FF_IDCT_SIMPLEARM -er n 设置错误残留为n 1 FF_ER_CAREFULL 缺省 2 FF_ER_COMPLIANT 3 FF_ER_AGGRESSIVE 4 FF_ER_VERY_AGGRESSIVE -ec bit_mask 设置错误掩蔽为bit_mask,该值为如下值的位掩码 1 FF_EC_GUESS_MVS (default=enabled) 2 FF_EC_DEBLOCK (default=enabled) -bf frames 使用frames B 帧，支持mpeg1,mpeg2,mpeg4 -mbd mode 宏块决策 0 FF_MB_DECISION_SIMPLE 使用mb_cmp 1 FF_MB_DECISION_BITS 2 FF_MB_DECISION_RD -4mv 使用4个运动矢量 仅用于mpeg4 -part 使用数据划分 仅用于mpeg4 -bug param 绕过没有被自动监测到编码器的问题 -strict strictness 跟标准的严格性 -aic 使能高级帧内编码 h263+ -umv 使能无限运动矢量 h263+ -deinterlace 不采用交织方法 -interlace 强迫交织法编码 仅对mpeg2和mpeg4有效。当你的输入是交织的并且你想要保持交织以最小图像损失的时候采用该选项。可选的方法是不交织，但是损失更大 -psnr 计算压缩帧的psnr -vstats 输出视频编码统计到vstats_hhmmss.log -vhook module 插入视频处理模块 module 包括了模块名和参数，用空格分开 D)音频选项 -ab bitrate 设置音频码率 -ar freq 设置音频采样率 -ac channels 设置通道 缺省为1 -an 不使能音频纪录 -acodec codec 使用codec编解码 E)音频/视频捕获选项 -vd device 设置视频捕获设备。比如/dev/video0 -vc channel 设置视频捕获通道 DV1394专用 -tvstd standard 设置电视标准 NTSC PAL(SECAM) -dv1394 设置DV1394捕获 -av device 设置音频设备 比如/dev/dsp F)高级选项 -map file:stream 设置输入流映射 -debug 打印特定调试信息 -benchmark 为基准测试加入时间 -hex 倾倒每一个输入包 -bitexact 仅使用位精确算法 用于编解码测试 -ps size 设置包大小，以bits为单位 -re 以本地帧频读数据，主要用于模拟捕获设备 -loop 循环输入流。只工作于图像流，用于ffserver测试 ### mencoder和ffmpeg参数详细说明文档 我在Linux上的命令： 视频转换命令： ffmpeg -i “/home/wangdianchen/5.wmv” -y -ab 32 -ar 22050 -b 800000 -s 640*480 “/home/wangdianchen/5.wmv.flv” 视频截图命令：ffmpeg -i “/home/wangdianchen/5.wmv” -y -f image2 -t 10 -s 300*200 “/home/wangdianchen/5.wmv.jpg” ffmpeg参数设定解说 -bitexact 使用标准比特率 -vcodec xvid 使用xvid压缩 -s 320×240 指定分辨率 -r 29.97 桢速率（可以改，确认非标准桢率会导致音画不同步，所以只能设定为15或者29.97）画面部分，选其一 -b <比特率> 指定压缩比特率，似乎ffmpeg是自动VBR的，指定了就大概是平均比特率，比如768，1500这样的就是原来默认项目中有的 -qscale <数值> 以<数值>质量为基础的VBR，取值0.01-255，约小质量越好 -qmin <数值> 设定最小质量，与-qmax（设定最大质量）共用，比如-qmin 10 -qmax 31 -sameq 使用和源同样的质量声音部分 -acodec aac 设定声音编码 -ac <数值> 设定声道数，1就是单声道，2就是立体声，转换单声道的TVrip可以用1（节省一半容量），高品质 的DVDrip就可以用2 -ar <采样率> 设定声音采样率，PSP只认24000 -ab <比特率> 设定声音比特率，前面-ac设为立体声时要以一半比特率来设置，比如192kbps的就设成96，转换默认比特率都较小，要听到较高品质声音的话建议设到160kbps（80）以上 -vol <百分比> 设定音量，某些DVDrip的AC3轨音量极小，转换时可以用这个提高音量，比如200就是原来的2倍这样，要得到一个高画质音质低容量的MP4的话，首先画面最好不要用固定比特率，而用VBR参数让程序自己去判断，而音质参数可以在原来的基础上提升一点，听起来要舒服很多，也不会太大（看情况调整 例子：ffmpeg -y -i “1.avi” -title “Test” -vcodec xvid -s 368×208 -r 29.97 -b 1500 -acodec aac -ac 2 -ar 24000 -ab 128 -vol 200 -f psp -muxvb 768 “1.mp4″ 解释：以上命令可以在Dos命令行中输入，也可以创建到批处理文件中运行。不过，前提是：要在ffmpeg所在的目录中执行（转换所在目录下面的cores子目录）。 参数： -y （覆盖输出文件，即如果1.mp4文件已经存在的话，不经提示就覆盖掉了） -i “1.avi” （输入文件是和ffmpeg在同一目录下的1.avi文件，可以自己加路径，改名字） -title “Test” （在PSP中显示的影片的标题） -vcodec xvid （使用XVID编码压缩视频，不能改的） -s 368×208 （输出的分辨率为368×208，注意片源一定要是16:9的不然会变形） -r 29.97 （帧数，一般就用这个吧） -b 1500 （视频数据流量，用-b xxxx的指令则使用固定码率，数字随便改，1500以上没效果；还可以用动态码率如：-qscale 4和-qscale 6，4的质量比6高） -acodec aac （音频编码用AAC） -ac 2 （声道数1或2） -ar 24000 （声音的采样频率，好像PSP只能支持24000Hz） -ab 128 （音频数据流量，一般选择32、64、96、128） -vol 200 （200%的音量，自己改） -f psp （输出psp专用格式） -muxvb 768 （好像是给PSP机器识别的码率，一般选择384、512和768，我改成1500，PSP就说文件损坏了） “1.mp4″ （输出文件名，也可以加路径改文件名） P.S. 版主机器强劲的话，可以多开几个批处理文件，让它们并行处理。 E:\ffmpeg.exe -i I:\1.wmv -b 360 -r 25 -s 320×240 -hq -deinterlace -ab 56 -ar 22050 -ac 1 D:\2.flv 附录： ### 文献管理软件 JabRef 快速入门 我曾经非常愚蠢地认为手工维护自己的参考文献库就可以了，但随着看过论文的增加，文献的管理成为一件痛苦的差事。最近才领略到使用文献管理软件的方便。 JabRef 的中文教程比较少而不全，所以就写了这篇博客，简要介绍一下这个软件的使用方法。 目录 1. 软件介绍 2. 建立数据库 3. 导入文献条目 4. 管理文献条目 5. 与 vim 结合使用 6. 其它应用 7. 结语 1. 软件介绍 JabRef 是一个开源的参考文献管理软件，使用 Java 语言编写，所以天生具有跨平台特性，通用于安装有 Java 支持的 Windows, Linux 和 Mac，软件主页在：http://jabref.sourceforge.net/。它可以很方便地管理下载到本机的文献，生成 BibTeX 文献数据库，供 LaTeX 或其它软件使用，可以与 Kile, Emacs, Vim, WinEdt 等多种软件结合使用。 JabRef 适合什么人使用？总的来说 JabRef 最大的特点就是使用 BibTeX 格式的数据库，所以它最适合 LaTeX 用户使用；如果仅仅使用它的管理功能，也可以用于本地电子书的管理；对于使用 M$ Office 写论文的用户来说，EndNote 是最好的选择，它能集成到 M$Word 中，所以不推荐使用 JabRef。 JabRef 当前最新版本是 2.4.1，如果你发现自己的 JabRef 不支持某些特性，最好检查一下版本信息。本文使用 Linux 下的 JabRef 演示，其它系统下应该没有什么不同。 2. 建立数据库 JabRef 的文献数据库是纯文本的 bib 文件，可以将该数据库文件放在该主题文献的目录下。比如要建立一个 p2p 方向相关文献的数据库，只需建立一个 p2p 目录，在 JabRef 中选择 File->New Database，然后 Ctrl-s，将该数据库起名 p2p.bib，保存在 p2p 目录下。然后将 File->Database properties 中的 Database Encoding 设置为 UTF-8（这是因为论文的作者可能是法国人和我们会经常用中文写些注释，所以最好用国际化的字符集）， Directory 都设置成点号 .（表示当前目录，这样你就可以将整个目录打个包，扔到另一台 Linux/Win/Mac 机器上照常使用）。 3. 导入文献条目 文献数据库的内容自然是一篇一篇的论文，每篇论文在数据库中占一条记录。那么如何添加论文呢？自然不必全部手工添加，几乎所有的数据库在提供论文下载的同时都有该论文 citation 信息的下载，下面这张图上是计算机科学类常用数据库网站的 citation 下载链接示例。也许你以前不知道它们是做什么用的，但你总能在文章下载页面的某个地方找到它们。 聪明如你，肯定知道该怎么做吧。点开 citation 的链接，将内容保存为相应的文件名。比如 BibTeX 格式的 citation 信息，将其保存到名为 xxx.bib 的纯文本文件中，然后到 JabRef 里选择 File->Import into current database，将该文件导入当前数据库，你就会发现数据库中多了一条记录。当然，JabRef 支持很多 citation 信息格式，但是既然 JabRef 采用 BibTeX 格式管理数据库，我们还是尽量下载 BibTeX 格式的 citation。 每次只导入一条记录未免太麻烦了些，由于很多参考文献信息都是纯文本格式的，那么我们可以将很多条记录分段拷贝到 xxx.bib(或者 xxx.ris 等) 里，然后集中导入。 如果你已经下载到了论文的 pdf 文件，知道论文的标题名和数据库名，那么你就不用再去网站下载 citation 信息，可以直接在 JabRef 中用标题名搜索该论文。比如你知道论文标题叫做 A Survey of xxxxxxx，可以从 IEEEXplore 数据库中获得，那么你可以直接在 JabRef 中选择 Web search->Search IEEEXplore，然后用标题名搜索，点 Fetch，就可以直接得到 citation 信息（但搜索可能出现错误，那么你就需要用 Google Scholar 并且到论文网站上下载了）。 4. 管理文献条目 文献数据库的条目建立起来了，但是这只是一些 citation 和 abstract 信息，那么如何将下载下来的论文 pdf/ps 文件和它们对应的条目关联起来呢？ 只需要将下载下来论文的文件名保存成特定的格式，一种方法是文件名中包含 BibTeXkey，如果是 A. Yao 在 2005 年发表的文章，文件名就起为 xxx-Yao2005-yyy.pdf；一种方法是文件名包含论文名。然后修改匹配规则：Options->Preferences->External Programs->Use Regular Expression Search 文本框，比如在当前目录下匹配包含 BibTeXkey 的文件：“./.*[bibtexkey].*\\.[extension]”，在当前目录下匹配包含论文名的文件：“./.*[title].*\\.[extension]”，在子目录中匹配包含 BibTeXkek 的文件：“**/.*[bibtexkey].*\\.[extension]”。如果我们把文献数据库 bib 文件和 pdf 文件放在同一目录下，只需要使用在当前目录下匹配即可。 文件名和匹配关系修改好了，那么我们就可以将论文记录关联到文件了。如果是一次导入很多文献，可以使用批量处理：Tools->Scan database->Sychronize file links，但是同步的时候不要选择 Check existing file links，那样会很慢；处理单一记录的方法是：双击某论文条目，或者选中后按 Ctrl-e，就可以编辑该条目。进入 General 选项卡，在 File 条目后面点 Auto，JabRef 就会按照匹配规则搜索匹配的文件，关联到该条目。如果能搜索到 pdf 文件，关联后该条目的前面会出现一个 pdf 图标，点击该图标，就可以直接打开该论文的 pdf 文件。除了自动匹配以外，也可以使用 Auto 旁边的 + 号手动添加文件。 当然了，文献条目的其它信息我们也可以编辑。比如 ACM 的 BibTeX 中往往不包含摘要信息，我们可以在 Ctrl-e 以后的 Abstract 选项卡中添加对应论文的摘要信息；Springer 的 ris 信息往往过于简单，我们也可以通过网页信息添加一些条目；如果你对某篇文献有深刻印象或者想记一下笔记，可以在 Review 选项卡中记录下自己的想法。 在一个文献数据库中，文献还可以分组。View->Toggle groups interface，可以新建、修改分组，这样有一个好处是可以将该数据库所属大方向的很多小方向分组浏览，对初期准备了解研究方向大致轮廓的研究人员很有帮助。 5. 与 vim 结合使用 前面说过，JabRef 可以和很多软件结合使用，但是有一些软件我并不熟悉，所以这里仅仅介绍一下 JabRef 和 vim 关联使用的技巧。 JabRef 是使用 vim server 和 vim 通信的，所以这要求双方使用同样的 vim server 名。在 JabRef 一端，Options->Preferences->External Programs->Vim Server Name 文本框中就是 vim server 名，你可以使用默认的 vim 服务器名 vim，也可以修改成任意名字，比如 solrexvim；在 vim 一端，编辑 LaTeX 文件时不要使用通常的命令启动 vim，要加上 vim 服务器名，比如 vim --servername solrexvim --remote-silent xxx.tex，这条命令的意思是：使用 vim 连接到服务器 solrexvim 修改 xxx.tex 文件，如果该服务器不存在，就创建它。 等 JabRef 和 Vim 都启动了以后，如果在编辑 tex 文件的时候想加入某条文献的引用，只需要在 JabRef 上方的工具栏中先选择出 Vim，然后再点击该图标，vim 光标所在位置就会自动加入该文献的引用。 6. 其它应用 总的来说，JabRef 的作用主要是参考文献管理工具，但是也可以使用它来做一些其它的工作，比如个人数字图书馆。每个人电脑里可能都有一些电子书，有的人特别多。为了查阅方便，一般都会把电子书分门别类放到一个目录树中，每次找文件都要进到很深的目录下；有时候为了系统兼容性，避免使用中文文件名，理解一个文件对应哪本电子书成为一件痛苦的事。如果使用 JabRef 作为文件管理工具，就可以根据作者，书名排序或者直接检索，会方便很多。 7. 结语 本文简要介绍了 JabRef 的基本使用方法。我也是刚刚接触这个软件，对其体会并不深刻，可能 JabRef 还有很多特性可以加以发掘，就留给大家一起探索吧。 ### JabRef 文獻資料庫管理軟體 這篇作為教學文格式，其實只是摸索出來的使用方式筆記。因為覺得 JabRef 真的不太好上手，官方網站的Documentation教學雖然詳盡，不過不太friendly…就邊學邊筆記一下… 以下為目錄： ### 1. 下載軟體 JabRef 的官方網站為 http://jabref.sourceforge.net/ ，下載區也標明了有 • 給 Windows 用的：檔名類似 JabRef-2.5-setup.exe • 給 Mac OS X 用的：檔名類似 JabRef-2.5.OSX.zip • 給 Linux或其他unix-like用的：檔名類似 JabRef-2.5.jar 若是在 Linux 作業系統下，要在 JabRef-2.5.jar 上面按右鍵→選擇 「以 Sun Java Runtime 開啟」，就可直接執行程式，不用安裝。 ### 2. 軟體初始化設定/說明 建立一個資料庫後，可新增 entry (條目) → type 選 『Article』 隨時可 Edit entry，下方就會出現 entry 的資訊，可手動填寫或如下文運用 BibTeX source 來自動填入資訊。 • File → Database properties → File directory: . /* 將資料庫的 bib 檔與相關文件檔（例如全文pdf檔）設定在同資料夾下 */ • Options → Preferences → BibTex key generator → Default pattern: [auth][year] /* 讓每個文獻都有自己專屬唯一的』名字』即 bibtexkey，形式可自己設定 */ • Options → Manage journal abbreviations → dowload → save /* 下載並儲存期刊名稱的縮寫資料。例如可存到與資料庫的 bib 檔同一資料夾下 */ • 假如是用 JabRef-2.5.jar 或者在 JabRef 裡選取 pdf 檔卻沒動靜的話： Options → Preferences → External programs → manage external file types → PDF: application 輸入設為 acroread（這是對於Linux系統；其他作業系統請設定為 pdf reader 的位置） ### 3. 加入論文資訊 在論文下載頁面，download citation → 選擇 『BibTex』格式 (其他可能還有 EndNote, RefWorks 等格式) 有兩種方法可匯入論文資訊： 1. 下載 BibTex file 後，用 JafRef 匯入： File → Import into current database 2. 複製 BibTex 資訊，然後貼到 new entry 的資料上去： New BibTex entry → Article → BibTex Source 所有的作者、期刊名稱、摘要….等資料就自動填好了 ### 4. 加入論文全文pdf檔連結 • 手動下載論文全文pdf檔後，放到與資料庫的 bib 檔同一資料夾下。 • Tools → Autogererate BibTex keys 在該論文的 entry 上按右鍵 → Copy BibTex key 然後將複製起來的資訊(bibtexkey)貼到pdf檔名上 • edit entry → General → File: Auto 從此 entry 前多一個pdf檔的圖示，可用來直接打開pdf檔 ### 5. 其他 Tools -> Abbreviate journal names (ISO) /* 可將期刊名稱改為縮寫樣式 */ 林怡萍 教授：做研究/學習事半功倍的好工具 其實這就是個資料庫管理軟體，也可以靈活運用，譬如拿來管理 樂譜資料.音樂檔.樂譜電子檔 ### 6. To be continued… Web search? ISI web of knowledge? citeulike? Acta Crystallographica, Section D 這本期刊網頁沒提供 bibtex = =+ .bib 檔與 LaTeX 引用文獻的寫法 ### Readings for Balanced Trees Readings for Balanced Trees: Handout from Weiss, pp 135-149 for AVL trees, and 165-170 for B-trees Balanced Trees The obvious idea is that a binary tree can have linear search time and insertion time properties if it, for instance, only has Right offspring... it degenerates into a linked list. No logarithmic advantage. Further trees mutate in shape depending on the policy for inserts and removes (figs. p. 136). So to preserve the logarithmic worst-case times one goes to a fair amount of bother to keep the trees balanced. None of these techniques is very easy: all call for fairly complex algorithms for insertion and deletion. In AVL trees, an operation called ROTATION is used to reorder nodes in the tree for balance. In B-trees (very useful in databases), the same goal is achieved by SPLITTING. AVL trees are binary, B-trees are not. Note also there are Red-Black trees, which are pretty popular. AVL trees: AVL tree is Binary search tree with balance condition. You can imagine several balance conditions, and the goal is to find one that has OK performance and OK costs to maintain. -- Root's Left and Right subtree have same height? nope, fig. 4.29. -- Every node's Left and Right subtree have same height? nope, can only guarantee if have exactly 2**n -1 nodes. AVL Balance Condition: -- Every node's Left and Right subtree can differ in height by at most one (1). By convention, the height of an empty tree is -1. Examples in Fig. 4.30. Worst case height is 1.44 logn, but in practice, height is about log (n+1) + .25. Checkout Fig. 4.31, and note that you have a Fibonacci-like recursion (which gives the 1.44 log bound): The left subtree is minimum size of height 7 and the right of minimum size of height 8. Thus we know N(h) = N(h-1)+ N(h-2) +1. For h=0, N(h) = 1; For h=1, N(h) = 2. Trick for binary search trees and other data structures: if there aren't going to be many deletions, use *lazy deletion*, which just marks a node as deleted and leaves it in place. Using lazy deletion, all the operations on AVL trees look quick except possibly insertion, which keeps tree balanced. Height information is kept in the node structure for each node and is used to keep tree balanced. One has to update this upon insertion, but major problem is that insertion can unbalance the tree. Luckily, a single local readjustment of nodes preserves binary search property and rebalances...it's a *rotation* (Fig. 4.32). See also 4.30, 4.33 Start at insertion, head up toward root of tree looking at balance info. If any out-of-balance node is found, rotate and quit. Example pp. 140-141. This is all very well but it's not good enough because sometimes we need a *double rotation*. Inserting into the middle'' subtree (Y in figure 4.32) can lead to problem not fixed by rotation, so need double rotation (fig. 4.34, 4.35). Programming information and tricks p. 145. Deletion even worse (as usual). B-Trees (p. 165ff) A special case of B-trees is the popular 2-3 trees (B-tree of order 3). B-trees not binary in general, bigger branching factor, good for organizing files on disks, directories, data bases, etc. B-trees (of order m) have following properties: Root is either a leaf or has between 2 and m children All nonleaf nodes but the root have between ceil(m/2) and m children. All leaves are at same depth. All data is stored in leaves, either keys or pointers to structures containing the keys. Interior nodes just have *pointers* to children and *values* giving the smallest values to be found in the correspoinding subtrees. Keys increase in value across subtrees: All keys in subtree p1 are < in p2. Example in fig. 4.63. Operations: Find: start at root, branch down to one of at most 3 children depending on the relation of the key we seek to the values stored in the root. etc. Insert: for a new key x, follow path as if for Find, and x goes in the leaf we find. No problem unless our addition causes too many occupants of a node (four for a 2-3 tree). In that case the node must be split: turn it into two nodes with 2 keys each and adjust the parent. BUT that might actually make too many children, like four, for the parent, so that means the parent must be split and each half gets 2 children. More examples p. 168,169. Only changes happen along the access path, but Weiss warns that it isn't easy and there are lots of cases. There are various other ways of rebalancing a B-tree evidently....like you could search for underfull sibs and skoosh keys over into them when you add to a node. This works for internal nodes too. Keeps nodes fuller but more complex routines. Actual (not lazy) Removal isn't too hard...combine singleton remaining keys with siblings, or if sib has 3 steal one and give it to the singleton. If sib has 2 keys, combine both into 3-key node, parent loses a child, which could cause repercussions upward. Generalizing this 2-3 tree algorithm to order m isn't hard...only have to take action on insertion when node has m keys already, when it splits into two of size ceil((m+1)/2), floor((m+1)/2) (recursively). Depth of B-tree is at most ceil(log to the base ceil(m/2) of n). In general at each node we have to figure out which branch to take, which with binary search over the possibly m entries takes O(log m). Insert, remove can require O(log m) to fix up node information. So worst-case for insert and remove is O(m logtothebase m n) = O((m/logm)logn), but Find is only O(log n). B-trees good for databases if whole Btree stored on disk, then you pay lots for every disk access. The number of disk accesses is O(logbasem n), and the O(log m) in-core search is quick by comparison, so maximize m to be largest that allows internal node to fit in a disk block. Likewise max. elements in leaf should just fill one disk block. Using insertion strategy here (not skooshing keys to sibs) yields predicted 69% occupancy (this is ln 2...can you explain why?). Exercises:( these are Weiss: 4.15, 4.16, 4.21, 4.36, 4.38) 1. a) Give a precise expression for the minimum number of nodes in an AVL tree of height h. b) What is the minimum number of nodes in an AVL tree of height 15? 2. Show the result of inserting 2,1,4,5,9,3,6,7 into an empty AVL tree. 3. a) How many bits are required per node to store the height of a node in an n-node AVL tree? b) What is the smallest AVL tree that overflows an 8-bit height counter? 4. a) Show the result of inserting the following keys into an initially-empty 2-3 tree: 3,1,4,5,9,2,6,8,7,0. b) Show the result of deleting 0 and then 9 from the 2-3 created in part (a). 5. A B* tree of order m is a B-tree in which each interior node has between 2m/3 and m children. Describe a method to perform insertion into a B* tree. ### Setting up a new remote git repository To collaborate in a distributed development process you’ll need to push code to remotely accessible repositories. This is somewhat of a follow-up to the previous article setting up a new rails app with git. It's good to know how this stuff works, but this is definitely the hard way. For no fuss git repository setup (especially if you want to collaborate with others) check out GitHub. ## For the impatient Set up the new bare repo on the server: $ ssh myserver.com
Welcome to myserver.com!
$mkdir /var/git/myapp.git && cd /var/git/myapp.git$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$exit Bye!  Add the remote repository to your existing local git repo and push: $ cd ~/Sites/myapp
$git remote add origin ssh://myserver.com/var/git/myapp.git$ git push origin master

Set the local master branch to track the remote branch.

Read further for a step-by-step explanation of what’s going on.

## Pre-flight sanity check

Setting up a remote repository is fairly simple but somewhat confusing at first. Firstly, let’s check out what remote repositories are being tracked in our git repo:

$cd ~/Sites/myapp$ git remote

None. Looking good. Now let’s list all the branches:

$git branch -a * master  Just one branch, the master branch. Let’s have a look at .git/config: $ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

A pretty bare-minimum config file.

## Creating the bare remote repository

Before we can push our local master branch to a remote repository we need to create the remote repository. To do this we’ll ssh in and create it on the server:


$ssh myserver.com Welcome to myserver.com!$ cd /var/git
$mkdir myapp.git$ cd myapp.git
$git --bare init Initialized empty Git repository in /var/git/myapp.git$ exit
Bye!


A short aside about what git means by bare: A default git repository assumes that you’ll be using it as your working directory, so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don’t need copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what “bare” means to git. Just the repository itself.

## Adding the remote repository to our local git repository configuration

Now that we’ve created the remote repository we’ll add it to our local repository as a remote server called “origin” using git remote add, which is just a nicer way of updating our config file for us:


$git remote add origin ssh://myserver.com/var/git/myapp.git Let’s see what it added to the config file: [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = ssh://myserver.com/var/git/myapp.git fetch = +refs/heads/*:refs/remotes/origin/* We now have a remote repository “origin” that will fetch all of it’s refs/heads/* branches and store them in our local repo in refs/remotes/origin/* when a git fetch is performed. ## Pushing to the remote repository The time has come to push our local master branch to the origin’s master branch. We do that using the git push <target> <local> command. $ git push origin master
from 0000000000000000000000000000000000000000
to   b379203bc187c2926f44a71eca3f901321ea42c6
Also local refs/remotes/origin/master
Generating pack...
Done counting 1374 objects.
Deltifying 1374 objects...
100% (1374/1374) done
Writing 1374 objects...
100% (1374/1374) done
Total 1374 (delta 89), reused 0 (delta 0)
refs/heads/master: 0000000000000000000000000000000000000000 -> b379203bc187c2926f44a71eca3f901321ea42c6


and that’s all, folks. Further pushes can be done by repeating the git push command.

Now you can tell your co-conspirators to:

$git clone ssh://myserver.com/var/git/myapp.git and push and pull to your heart’s content. ## Track the remote branch You can specify the default remote repository for pushing and pulling using git-branch’s track option. You’d normally do this by specifying the --track option when creating your local master branch, but as it already exists we’ll just update the config manually like so: [branch "master"] remote = origin merge = refs/heads/master  Now you can simply git push and git pull. ## Sharing the remote repository with the world If you want to set it up as a public repository be sure to check out the Git manual’s chapter on public git repositories. ## Working with remote repository branches git remote show is used to inspect a remote repository. It goes and checks the remote repository to see what branches have been added and removed since the last git fetch. Doing a git remote show at the moment only shows us the remote repo’s master branch which we pushed earlier: $ git remote show origin
* remote origin
URL: ssh://myserver.com/var/git/myapp.git
Tracked remote branches
master

Let’s create a new local git repository and push to a new branch on the remote repository. We can then use git remote show to see the new remote branch, git fetch to mirror it into our local repo and git checkout --track -b to create a local branch to do some work on it.

We’ll start by creating a new local repo and pushing some code to a new branch in the remote repository.

$mkdir /tmp/other-git$ cd /tmp/other-git
$git init Initialized empty Git repository in /tmp/other-git$ git remote add origin ssh://myserver.com/var/git/myapp.git
$echo "Rails 2... woo" > afile$ git add afile
$git commit -m "Added afile" Created initial commit 0ac9a74: Added afile 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 something$ git push origin master:rails-2
from 0000000000000000000000000000000000000000
to   0ac9a7457f4b21c9e058d4c54d262584bf35e528
Also local refs/remotes/origin/rails-2
Generating pack...
Done counting 3 objects.
Deltifying 3 objects...
100% (3/3) done
Writing 3 objects...
100% (3/3) done
Total 3 (delta 0), reused 0 (delta 0)
Unpacking 3 objects...
100% (3/3) done
refs/heads/rails-2: 0000000000000000000000000000000000000000 -> 0ac9a7457f4b21c9e058d4c54d262584bf35e528


Now let’s switch back to our old git repository and see if it detects the new branch on the remote repository:

$git remote show origin * remote origin URL: ssh://myserver.com/var/git/myapp.git New remote branches (next fetch will store in remotes/origin) rails-2 Tracked remote branches master  Let’s update our mirror of the remote repository by doing a git fetch: $ git fetch
* refs/remotes/origin/master: storing branch 'rails-2' of ssh://myserver.com/var/git/myapp.git
commit: b379203
$git remote show origin * remote origin URL: ssh://myserver.com/var/git/myapp.git Tracked remote branches master rails-2 We should now be able to see this in a our list of remote branches: $ git branch -a
* master
origin/rails-2
origin/master

If we then wanted to do some work on this remote rails-2 branch we create a new local tracking branch like so:

$git checkout --track -b rails-2 origin/rails-2 Branch rails-2 set up to track remote branch refs/remotes/origin/rails-2. Switched to a new branch "rails-2"  To keep up-to-date and push new changesets we simply use git push and git pull when working in the local rails-2 branch. Also notice, like we manually changed for master, .git/config has a new entry for this new tracking branch: [branch "rails-2"] remote = origin merge = refs/heads/rails-2  ## Further Reading Sourcemage’s Git Guide has some very very handy real-life examples of git commands you’ll often need. So now you know the hard way. For no fuss Git repository setup (especially if you want to collaborate with others) check out GitHub. http://toolmantim.com/thoughts/setting_up_a_new_remote_git_repository ### Git详解（二） Git中级用法： Ignoring files 项目里总会出现你不想跟踪的文件。当然这些文件你不对它们进行git add操作就行了，但是这样也很麻烦， 如果使用git add .命令和git commit -a命令呢？你能告诉git去忽略一些文件，我们只需要在我们工作目录顶级创建一个.gitignore文件就可以了。就像这样： 123456789101112131415$ vi .gitignore  # Lines starting with '#' are considered comments.# Ignore any file named foo.txt.foo.txt# Ignore (generated) html files,*.html# except foo.html which is maintained by hand.!foo.html# Ignore objects and archives.*.[oa]# Ignore log direction and .DS_Store files/log.DS_Store

Rebasing

1$git checkout -b mywork origin 创建一个新分支并选中它。 然后你做了一些改变： 1234$ vi file.txt$git commit$ vi otherfile.txt$git commit 与此同时，另外一些人在origin branch 上也做了一些工作，创建了两个提交。这就意味着origin和mywork会有冲突。在这一点上，你可以用pull来merge你的改变，结果是创建了一个新的merge commit。 但是你只想在mywork分支上保留你的commit历史，而不需要任何merge，那么你可以选择使用git rebase： 12$ git checkout mywork$git rebase origin 这个命令会把你每次从mywork的提交都会以补丁的形式暂时保存在一个叫.git/rebase的目录下，当更新到origin的最新版本的时候，就会把这个补丁给新的mywork打回去，这样，就不会有任何merge commit在历史记录里。 一旦你的‘mywork’引用指向的是新被创建的那个commit对象，那么老的commit对象会被遗弃，如果你运行垃圾回收器（git gc），它们很可能会被移除。 如果rebase的过程发现冲突，那么在你解决冲突以后，使用git add命令把它们再次更新到git index里，然后你要使用： 1$ git rebase --continue

1$git rebase --abort Interactive Rebasing 你可以使用互动的rebase，使用这个模式，你可以在把它们提交到某地之前重写你自己的commit对象。 它可以让你容易分离merge和re-order commit， 你也可以清除已经pull到本地的commits。 你可以在git rebase后面加参数 －i，和 －－interactive来给commit应用interactive模式。$ git rebase -i origin/master

pick fc62e55 added file_size
pick 9824bf4 fixed little thing
pick 21d80a5 added number to log
pick 76b9da6 added the apply command
pick c264051 Revert “added file_size” - not implemented correctly

# Rebase f408319..b04dc3d onto f408319
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

(action) (partial-sha) (short commit message)

1git add -i

123456789101112$>git add -istaged unstaged path1: unchanged +4/-0 assets/stylesheets/style.css2: unchanged +23/-11 layout/book_index_template.html3: unchanged +7/-7 layout/chapter_template.html4: unchanged +3/-3 script/pdf.rb5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown *** Commands ***1: status 2: update 3: revert 4: add untracked5: patch 6: diff 7: quit 8: helpWhat now> 看到那些命令了吧。你可以选择，如果不懂，可以输入8，然后回车，就会输出帮助： 12345678910status - show paths with changesupdate - add working tree state to the staged set of changesrevert - revert staged set of changes back to the HEAD versionpatch - pick hunks and update selectivelydiff - view diff between HEAD and indexadd untracked - add contents of untracked files to the staged set of changes*** Commands ***1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elpWhat now> 当然你不输入数字，直接输入help也是一样的效果。 这种模式下，你有多种选择。当你选择完毕以后，那么输入7或q退出，然后git commit你的改变，记住这里不要用git commit －a，否则你前面都做无用功了。 Stashing 当你在工作中发现一个不相关的但是却显而易见微不足道的bug的时候，你可能想在继续你的工作之前修复它。你可以用git stash来保存当前的工作状态，在修复完那个bug之后，再回来继续。 1$ git stash "work in progress for foo feature"

… edit and test …

1$git commit -a -m "fix：bugs" 然后，你可以回到你之前的工作状态： 1$ git stash apply

Stash Queue

123$>git stash liststash@{0}: WIP on book: 51bea1d... fixed imagesstash@{1}: WIP on master: 9705ae6... changed the browse code to the official repo 你可以使用命令来回到你想去的那个stash： 1git stash apply stash@{1} 清除stash可以用命令： 1git stash clear Git Treeishes 除了吃力的写出那40位的sha乱码来引用一个commit对象或是tree对象之外，还有很多方法。在Git里这些被称为 treeish。 Partial Sha 如果你的commit sha是980e3ccdaac54a0d4de358f3fe5d718027d96aae，git可以通过下列标识来识别它： 980e3ccdaac54a0d4de358f3fe5d718027d96aae 980e3ccdaac54a0d4 980e3cc 我自己试了试前5位，ms也能识别。 Branch, Remote or Tag Name 你也可以用branch，remote，tag name代替一个sha。 如果你的master 分支是在980e3 commit上，而且你也把它push到了origin，并且它也有一个tag name叫v1.0，那么下面这些是等价的： 980e3ccdaac54a0d4de358f3fe5d718027d96aae origin/master refs/remotes/origin/master master refs/heads/master v1.0 refs/tags/v1.0 都代表同一个commit object 123$ git log master $git log refs/tags/v1.0 输出是一样的。 Date Spec 12git log master@{yesterday}git log master@{1 month ago} 注意这种格式的，得到的sha会是不同的。 Ordinal Spec git log [email protected]{5}, 同上。 Carrot Parent 这会给你一个特别commit的第n次父类。这个格式仅对merge commits有用 － commit对象有大于一个的父类。 master^2 Tilde Spec 给你第n次commit对象的外祖父类。上上级。 master~2 这会返回这个master指向的commit对象的第一个parent的第一个parent。等价于： master^^ 你也可以这么做： master^^^^^^ master~3^~2 master~6 Tree Pointer master^{tree} Blob Spec master:/path/to/file Range 你可能指定一个commit的范围，那么： 7b593b5..51bea1 它会包含从7b593b5开始的每次提交： 7b593b5.. Tracking Branches 一个tracking branche是指链接到远程分支的一个本地分支。当你往这个分支push和pull的时候，会自动的的push或pull到远程的那个分支。 git clone命令会自动的设置一个master分支，它是origin/master的tracking branch。 你也可以通过–track参数手动创建一个tracking branch： 1git branch --track experimental origin/experimental 然后，当你运行：$ git pull experimental

Finding with Git Grep

1234567891011$git grep defconfig/boot.rb:RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)config/boot.rb: def boot!config/boot.rb: def booted?config/boot.rb: defined? Rails::Initializerconfig/boot.rb: def pick_bootconfig/boot.rb: def vendor_rails?config/boot.rb: def preinitializeconfig/boot.rb: def preinitializer_pathconfig/boot.rb: def run... 如果我想看行数，我也可以加－n参数： 1234567891011$ git grep -n defconfig/boot.rb:4:RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)config/boot.rb:8:    def boot!config/boot.rb:15:    def booted?config/boot.rb:16:      defined? Rails::Initializerconfig/boot.rb:19:    def pick_bootconfig/boot.rb:23:    def vendor_rails?config/boot.rb:27:    def preinitializeconfig/boot.rb:31:    def preinitializer_pathconfig/boot.rb:37:    def run...

1234567$git grep --name-only defconfig/boot.rbconfig/environment.rbconfig/initializers/inflections.rbconfig/initializers/new_rails_defaults.rbconfig/routes.rb... 我们也可以看有多少行匹配def： 123456$ git grep -c defconfig/boot.rb:18config/environment.rb:9config/initializers/inflections.rb:1config/initializers/new_rails_defaults.rb:2config/routes.rb:2

Undoing in Git - Reset, Checkout and Revert

Fixing un-committed mistakes

1$git reset --hard HEAD 这个命令会扔掉你所有的改变，包括已经加到git index里的改变。 如果你只是想restore一个文件，那么使用checkout： 12$ git checkout -- hello.rb$git checkout HEAD hello.rb Fixing committed mistakes 对于已经提交的错误，有两个方法： 你可以创建一个新的commit，去undo你旧的提交做的那些事情。这是个正确的做法。 你也可以返回来修改旧的commit。一般不要这样做。 Fixing a mistake with a new commit 使用git revert命令： 1$ git revert HEAD

1$git revert HEAD^ Fixing a mistake by modifying a commit 可以使用git rebase -i 修改你的commit，或用–amend参数。 Maintaining Git Ensuring good performance 对于一个大的git仓库，可能会有一些历史信息占用了太多的空间或内存。那么可以用命令： 12345678910git gc输出：git gcCounting objects: 810, done.Compressing objects: 100% (723/723), done.Writing objects: 100% (810/810), done.Total 810 (delta 95), reused 0 (delta 0)Removing duplicate objects: 100% (256/256), done. Ensuring reliability git fsck命令会在代码仓里执行一些检查并返回一些问题报告，最常见的警告是关于dangling对象： 12git fsckdangling blob 1b2b2a5e3f9518e2aa243337683391451b281d7c Setting Up A Public Repository 假设你的私人repos是在~/.proj下面。我们首先要创建一个repos的新的clone，并且告诉git-daemon 它是public的： 12$ git clone --bare ~/proj proj.git$touch proj.git/git-daemon-export-ok 这个结果是导出一个‘赤裸的’git repos。 下一步copy proj.git到你计划作为一个public repos的服务器。你可以用scp，rsync，或者其他。 Exporting a git repository via the git protocol 这是首选的方法。 可以启动git daemon服务，详细的看：http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html Exporting a git repository via http 1234$ mv proj.git /home/you/public_html/proj.git$cd proj.git$ git --bare update-server-info$chmod a+x hooks/post-update 最后两行代码可以参看： http://www.kernel.org/pub/software/scm/git/docs/git-update-server-info.html http://www.kernel.org/pub/software/scm/git/docs/githooks.html 这样就可以了： 1$ git clone http://yourserver.com/~you/proj.git

Setting Up a Private Repository

Repo Access over SSH

12$git clone --bare /home/user/myrepo/.git /tmp/myrepo.git$ scp -r /tmp/myrepo.git myserver.com:/opt/git/myrepo.git

Multiple User Access using Gitosis

http://www.urbanpuddle.com/articles/2008/07/11/installing-git-on-a-server-ubuntu-or-debian

Related posts:

1. Git一分钟教程 流程：取代码 → 每次工作前更新代码到最新版本 → 修改代码 → 提交代码到服务器 取代码及修改全局设置 设置用户名与邮箱 git...
2. Git服务器安装 Git on Ubuntu Server 安装Git-Core: sudo apt-get update # 可选步骤...
3. Git详解（一） 我用git最开始是在github，每次提交代码以后，右上角的部分就会显示这些信息，类似于下面的： commit  fa6f27b7de063c2f301b0e7148b5bd5e813faa98 tree       5e7a19c158b89fbc52a078771a833ee839727404 parent   76f31606376180ca88efa12be341dbb14fb06fdf 咋一看，这40位的乱码挺吓人的，但是你了解它的作用就不会被吓到了。 这是object name，是作为你每次提交的信息标识。这是用SHA1加密hash函数根据你的对象的内容算出来的。Git的一些优点：...
4. Satellite: a self-syncing distributed wiki 介绍 satellite is a self-syncing distributed wiki with file uploads...

Related posts brought to you by Yet Another Related Posts Plugin.