repository and is not part of thegit commit amend,yet its child 怎么解决

Everything about Git, SVN, and other VCS08:53 by youxin, ... 阅读,
文件共享的问题
所有的版本控制系统都需要解决这样一个基础问题:怎样让系统允许用户共享信息,而不会让他们因意外而互相干扰?版本库里意外覆盖别人的更改非常的容易。
考虑的情景。假设我们有两个共同工作者,Harry 和 Sally。他们想同时编辑版本库里的同一个文件,如果 Harry 先保存它的修改,(过了一会)Sally 可能凑巧用自己的版本覆盖了这些文件,Harry 的更改不会永远消失(因为系统记录了每次修改),但 Harry 所有的修改不会出现在 Sally 新版本的文件中,因为她没有在开始的时候看到 Harry 的修改。所以 Harry 的工作还是丢失了&至少是从最新的版本中丢失了&而且可能是意外的。这就是我们要明确避免的情况!
图&1.2.&需要避免的问题
1.3.2.&&锁定-修改-解锁&方案
许多版本控制系统使用锁定-修改-解锁机制解决这种问题,在这样的模型里,在一个时间段里版本库的一个文件只允许被一个人修改。首先在修改之前,Harry要&锁定&住这个文件,锁定很像是从图书馆借一本书,如果Harry锁住这个文件,Sally不能做任何修改,如果Sally想请求得到一个锁,版本库会拒绝这个请求。在Harry结束编辑并且放开这个锁之前,她只可以阅读文件。Harry解锁后,就要换班了,Sally得到自己的轮换位置,锁定并且开始编辑这个文件。描述了这样的解决方案。
图&1.3.&&锁定-修改-解锁&方案
锁定-修改-解锁模型有一点问题就是限制太多,经常会成为用户的障碍:
锁定可能导致管理问题。有时候 Harry 会锁住文件然后忘了此事,这就是说 Sally 一直等待解锁来编辑这些文件,她在这里僵住了。然后 Harry 去旅行了,现在 Sally 只好去找管理员放开锁,这种情况会导致不必要的耽搁和时间浪费。
锁定可能导致不必要的串行开发。如果 Harry 编辑一个文件的开始,Sally 想编辑同一个文件的结尾,这种修改不会冲突,设想修改可以正确的合并到一起,他们可以轻松的并行工作而没有太多的坏处,没有必要让他们轮流工作。
锁定可能导致错误的安全状态。假设 Harry 锁定和编辑一个文件 A,同时 Sally 锁定并编辑文件 B。但是如果 A 和 B 互相依赖,修改导致它们不兼容会怎么样呢?这样 A 和 B 不能正确的工作了,锁定机制对防止此类问题将无能为力&从而产生了一种处于安全状态的假相。很容易想象 Harry 和 Sally 都以为自己锁住了文件,而且从一个安全,孤立的情况开始工作,因而没有尽早发现他们不匹配的修改。锁定经常成为真正交流的替代品。
1.3.3.&&拷贝-修改-合并&方案
Subversion, CVS, and many other version control systems use a&copy-modify-merge&model as an alternative to locking. In this model, each user's client contacts the project repository and creates a personal working copy. Users then work simultaneously and independently, modifying their private copies. Finally, the private copies are merged together into a new, final version. The version control system often assists with the merging, but ultimately, a human being is responsible for making it happen correctly.
这是一个例子,Harry 和 Sally 为同一个项目各自建立了一个工作副本,工作是并行的,修改了同一个文件 A,Sally 首先保存修改到版本库,当 Harry 想去提交修改的时候,版本库提示文件 A 已经过期,换句话说,A在他上次更新之后已经更改了,所以当他通过客户端请求合并版本库和他的工作副本之后,碰巧 Sally 的修改和他的不冲突,所以一旦他把所有的修改集成到一起,他可以将工作拷贝保存到版本库,和展示了这一过程。
图&1.4.&&拷贝-修改-合并&方案
图&1.5.&&拷贝-修改-合并&方案(续)
但是如果 Sally 和 Harry 的修改交迭了该怎么办?这种情况叫做冲突,这通常不是个大问题,当 Harry 告诉他的客户端去合并版本库的最新修改到自己的工作副本时,他的文件 A 就会处于冲突状态:他可以看到一对冲突的修改集,并手工的选择保留一组修改。需要注意的是软件不能自动的解决冲突,只有人可以理解并作出智能的选择,一旦 Harry 手工的解决了冲突&也许需要与 Sally 讨论&它可以安全的把合并的文件保存到版本库。
拷贝-修改-合并模型感觉有一点混乱,但在实践中,通常运行的很平稳,用户可以并行的工作,不必等待别人,当工作在同一个文件上时,也很少会有交迭发生,冲突并不频繁,处理冲突的时间远比等待解锁花费的时间少。
最后,一切都要归结到一条重要的因素:用户交流。当用户交流贫乏,语法和语义的冲突就会增加,没有系统可以强制用户完美的交流,没有系统可以检测语义上的冲突,所以没有任何证据能够承诺锁定系统可以防止冲突,实践中,锁定除了约束了生产力,并没有做什么事。
锁定-修改-解锁模型被认为不利于协作,但有时候锁定会更好。
拷贝-修改-合并模型假定文件是可以根据上下文合并的:就是版本库的文件主要是以行为基础的文本文件(例如程序源代码)。但对于二进制格式,例如艺术品或声音,在这种情况下,十分有必要让用户轮流修改文件,如果没有线性的访问,有些人的许多工作就最终要被放弃。
尽管 Subversion 一直主要是一个拷贝-修改-合并系统,但是它也意识到了需要锁定一些文件,并且提供这种锁定机制,这个特性的讨论可以见。
2.&Subversion 的版本控制
We've mentioned already that Subversion is a modern, network-aware version control system. As we described in&&(our high-level version control overview), a repository serves as the core storage mechanism for Subversion's versioned data, and it's via working copies that users and their software programs interact with that data. In this section, we'll begin to introduce the specific ways in which Subversion implements version control.
2.1.&Subversion 版本库
Subversion implements the concept of a version control repository much as any other modern version control system would. Unlike a working copy, a Subversion repository is an abstract entity, able to be operated upon almost exclusively by Subversion's own libraries and tools. As most of a user's Subversion interactions involve the use of the Subversion client and occur in the context of a working copy, we spend the majority of this book discussing the Subversion working copy and how to manipulate it. For the finer details of the repository, though, check out&.
2.2.&修订版本
A Subversion client commits (that is, communicates the changes made to) any number of files and directories as a single atomic transaction. By atomic transaction, we mean simply this: either all of the changes are accepted into the repository, or none of them is. Subversion tries to retain this atomicity in the face of program crashes, system crashes, network problems, and other users' actions.
Each time the repository accepts a commit, this creates a new state of the filesystem tree, called a&revision. Each revision is assigned a unique natural number, one greater than the number assigned to the previous revision. The initial revision of a freshly created repository is numbered 0 and consists of nothing but an empty root directory.
可以更形象的描述版本库,想象有一组修订号,从 0 开始,从左到右,每一个修订号有一个目录树挂在它下面,每一个树好像是一次提交后的版本库&快照&。
图&1.6.&Tree changes over time
Unlike most version control systems, Subversion's revision numbers apply to&the entire repository tree, not individual files. Each revision number selects an entire tree, a particular state of the repository after some committed change. Another way to think about it is that revision N represents the state of the repository filesystem after the Nth commit. When Subversion users talk about&&revision 5 of&foo.c,&&they really mean&&foo.c&as it appears in revision 5.&&Notice that in general, revisions N and M of a file do&not&necessarily differ! Many other version control systems use per-file revision numbers, so this concept may seem unusual at first. (Former CVS users might want to see&&for more details.)
表&1.1.&版本库访问 URL
模式访问方法
直接版本库访问(本地磁盘)
通过配置Subversion的Apache服务器的WebDAV协议
Same as&http://, but with SSL encryption
通过定制的协议访问&svnserve&服务器
svn+ssh://
Same as&svn://, but through an SSH tunnel
Subversion 的工作副本
一个 Subversion工 作副本是你本地机器上的一个普通目录,保存着一些文件,你可以任意的编辑文件,而且如果是源代码文件,你可以像平常一样编译,你的工作副本是你的私有工作区,在你明确的做了特定操作之前,Subversion 不会把你的修改与其他人的合并,也不会把你的修改展示给别人,你甚至可以拥有同一个项目的多个工作副本。
当你在工作副本作了一些修改并且确认它们工作正常之后,Subversion 提供了一个命令可以&发布&你的修改给项目中的其他人(通过写到版本库),如果别人发布了各自的修改,Subversion 提供了手段可以把这些修改与你的工作目录进行合并(通过读取版本库)。
工作副本也包括一些由 Subversion 创建并维护的额外文件,用来协助执行命令。通常情况下,你的工作副本的每个文件夹都有一个以&.svn&为名的文件夹,也被叫做工作副本的管理目录,这个目录里的文件能够帮助 Subversion 识别哪些文件做过修改,哪些文件相对于别人的工作已经过期。
While&.svn&is the de facto name of the Subversion administrative directory, Windows users may run into problems with the ASP.NET Web application framework disallowing access to directories whose names begin with a dot (.). As a special consideration to users in such situations, Subversion will instead use&_svn&as the administrative directory name if it finds a variable named&SVN_ASP_DOT_NET_HACK&in its operating environment. Throughout this book, any reference you find to&.svn&applies also to&_svn&when this&&ASP.NET hack&&is in use.
2.4.1.&工作副本的工作方式
How Working Copies Track the Repository
For each file in a working directory, Subversion records two essential pieces of information in the&.svn/&administrative area:
What revision your working file is based on (this is called the file's&working revision)
A timestamp recording when the local copy was last updated by the repository
Given this information, by talking to the repository, Subversion can tell which of the following four states a working file is in:
Unchanged, and current
The file is unchanged in the working directory, and no changes to that file have been committed to the repository since its working revision. An&svn commit&of the file will do nothing, and an&svn update&of the file will do nothing.
Locally changed, and current
The file has been changed in the working directory, and no changes to that file have been committed to the repository since you last updated. There are local changes that have not been committ thus an&svn commit&of the file will succeed in publishing your changes, and an&svn update&of the file will do nothing.
Unchanged, and out of date
The file has not been changed in the working directory, but it has been changed in the repository. The file should eventually be updated in order to make it current with the latest public revision. An&svn commit&of the file will do nothing, and an&svn updateof the file will fold the latest changes into your working copy.
Locally changed, and out of date
The file has been changed both in the working directory and in the repository. An&svn commit&of the file will fail with an &out-of-date& error. The file sho an&svn update&command will attempt to merge the public changes with the local changes. If Subversion can't complete the merge in a plausible 合理的way automatically, it leaves it to the user to resolve the conflict.
This may sound like a lot to keep track of, but the&svn status&command will show you the state of any item in your working copy. For more information on that command, see&.
上面一段的翻译:
For each file in a working directory, Subversion records (among other things) two essential pieces of information:
作为工作文件基准的版本(叫做文件的工作版本)
本地副本最近一次被版本库更新的时间戳。
给定这些信息,通过与版本库通讯,Subversion可以告诉我们工作文件是处于如下四种状态的那一种:
未修改且是当前的
文件在工作目录里没有修改,在工作版本之后没有修改提交到版本库。svn commit&操作不做任何事情,svn update&不做任何事情。
本地已修改且是当前的
在工作目录已经修改,从基本修订版本之后没有修改提交到版本库。本地修改没有提交,因此&svn commit&会成功提交,svn update&不做任何事情。
本地未修改,已过时
这个文件在工作目录没有修改,但在版本库中已经修改了。这个文件最终将更新到最新版本,成为当时的公共修订版本。svn commit&不做任何事情,svn update&将会取得最新的版本到工作副本。
本地已修改,已过时
这个文件在工作目录和版本库都得到修改。一个&svn commit&将会失败,这个文件必须首先更新,svn update&命令会合并公共和本地修改,如果 Subversion 不可以自动完成,将会让用户解决冲突。
Mixed Revision Working Copies
As a general principle, Subversion tries to be as flexible as possible. One special kind of flexibility is the ability to have a working copy containing files and directories with a mix of different working revision numbers. Unfortunately, this flexibility tends to confuse a number of new users. If the earlier example showing mixed revisions perplexed you, here's a primer on why the feature exists and how to make use of it.
Updates and commits are separate
One of the fundamental rules of Subversion is that a &push& action does not cause a &pull,& nor vice versa. Just because you're ready to submit new changes to the repository doesn't mean you're ready to receive changes from other people. And if you have new changes still in progress,&svn update&should gracefully merge repository changes into your own, rather than forcing you to publish them.(svn update会并没有commit)
The main side effect of this rule is that it means a working copy has to do extra bookkeeping 记账to track mixed revisions as well as be tolerant of the mixture. It's made more complicated by the fact that directories themselves are versioned.
这个规则的主要副作用就是,工作副本需要记录额外的信息来追踪混合修订版本,并且也需要能容忍这种混合,当目录本身也是版本化的时候情况更加复杂。
举个例子,假定你有一个工作副本,修订版本号是10。你修改了&foo.html,然后执行&svn commit,在版本库里创建了修订版本15。当成功提交之后,许多用户希望工作副本完全变成修订版本15,但是事实并非如此。修订版本从10到15会发生任何修改,可是客户端在运行&svn update&之前不知道版本库发生了怎样的改变,svn commit&不会拖出任何新的修改。另一方面,如果&svn commit&会自动下载最新的修改,可以使得整个工作副本成为修订版本15&但是,那样我们会打破&推&和&拉&完全分开的原则。因此,Subversion 客户端最安全的方式是标记一个文件&&foo.html&&为修订版本15,工作副本余下的部分还是修订版本10。只有运行&svn update&才会下载最新的修改,整个工作副本被标记为修订版本15。
For example, suppose you have a working copy entirely at revision 10. You edit the file&foo.html&and then perform an&svn commit, which creates revision 15 in the repository. After the commit succeeds, many new users would expect the working copy to be entirely at revision 15, but that's not the case! Any number of changes might have happened in the repository between revisions 10 and 15. The client knows nothing of those changes in the repository, since you haven't yet run&svn update, and&svn commit&doesn't pull down new changes. If, on the other hand,&svn commit&were to automatically download the newest changes, it would be possible to set the entire working copy to revision 15&but then we'd be breaking the fundamental rule of &push& and &pull& remaining separate actions. Therefore, the only safe thing the Subversion client can do is mark the one file&foo.html&as being at revision 15. The rest of the working copy remains at revision 10. Only by running&svn update&can the latest changes be downloaded and the whole working copy be marked as revision 15.
Mixed revisions are normal
The fact is,&every time&you run&svn commit&your working copy ends up with some mixture of revisions. The things you just committed are marked as having larger working revisions than everything else. After several commits (with no updates in between), your working copy will contain a whole mixture of revisions. Even if you're the only person using the repository, you will still see this phenomenon. To examine your mixture of working revisions, use the&svn status&command with the&--verbose&option (see&&for more information).
Often, new users are completely unaware that their working copy contains mixed revisions. This can be confusing, because many client commands are sensitive to the working revision of the item they're examining. For example, the&svn log&command is used to display the history of changes to a file or directory (see&). When the user invokes this command on a working copy object, he expects to see the entire history of the object. But if the object's working revision is quite old (often because&svn update&hasn't been run in a long time), the history of the&older&version of the object is shown.
Mixed revisions are useful
If your project is sufficiently complex, you'll discover that it's sometimes nice to forcibly&backdate&(or update to a revision older than the one you already have) portions of your working copy to you'll learn how to do that in&. Perhaps you'd like to test an earlier version of a submodule contained in a subdirectory, or perhaps you'd like to figure out when a bug first came into existence in a specific file. This is the &time machine& aspect of a version control system&the feature that allows you to move any portion of your working copy forward and backward in history.
Mixed revisions have limitations
However you make use of mixed revisions in your working copy, there are limitations to this flexibility.
First, you cannot commit the deletion of a file or directory that isn't fully up to date. If a newer version of the item exists in the repository, your attempt to delete will be rejected to prevent you from accidentally destroying changes you've not yet seen.
Second, you cannot commit a metadata change to a directory unless it's fully up to date. You'll learn about attaching &properties& to items in&. A directory's working revision defines a specific set of entries and properties, and thus committing a property change to an out-of-date directory may destroy properties you've not yet seen.
We covered a number of fundamental Subversion concepts in this chapter:
We introduced the notions of the central repository, the client working copy, and the array of repository revision trees.
We saw some simple examples of how two collaborators can use Subversion to publish and receive changes from one another, using the &copy-modify-merge& model.
We talked a bit about the way Subversion tracks and manages information in a working copy.
At this point, you should have a good idea of how Subversion works in the most general sense. Armed with this knowledge, you should now be ready to move into the next chapter, which is a detailed tour of Subversion's commands and features.
Chapter&2.&Basic Usage
Table of Contents
Now we will go into the details of using Subversion. By the time you reach the end of this chapter, you will be able to perform all the tasks you need to use Subversion in a normal day's work. You'll start with getting your files into Subversion, followed by an initial checkout of your code. We'll then walk you through making changes and examining those changes. You'll also see how to bring changes made by others into your working copy, examine them, and work through any conflicts that might arise.
Note that this chapter is not meant to be an exhaustive list of all of Subversion's commands&rather, it's a conversational introduction to the most common Subversion tasks that you'll encounter. This chapter assumes that you've read and understood&&and are familiar with the general model of Subversion. For a complete reference of all commands, see&.
Before reading on, here is the most important command you'll ever need when using Subversion:&svn help. The Subversion command-line client is self-documenting&at any time, a quick&svn help&subcommand&will describe the syntax, options, and behavior of the subcommand.
$ svn help import
import: Commit an unversioned file or tree into the repository.
usage: import [PATH] URL
Recursively commit a copy of PATH to URL.
If PATH is omitted '.' is assumed.
Parent directories are created as necessary in the repository.
If PATH is a directory, the contents of the directory are added
directly under URL.
Unversionable items such as device files and pipes are ignored
if --force is specified.
Valid options:
-q [--quiet]
: print nothing, or only summary information
-N [--non-recursive]
: try --depth=files or --depth=immediates
--depth ARG
: limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
Getting Data into Your Repository
You can get new files into your Subversion repository in two ways:&svn import&and&svn add. We'll discuss&svn import&now and will discusssvn add&later in this chapter when we review a typical day with Subversion.
svn import 不要求working copy
The&svn import&command is a quick way to copy an unversioned tree of files into a repository, creating intermediate directories as necessary.&svn import&doesn't require a working copy, and your files are immediately committed to the repository. You typically use this when you have an existing tree of files that you want to begin tracking in your Subversion repository. For example:
svn import&是将未版本化文件导入版本库的最快方法,会根据需要创建中介目录。svn import&不需要一个工作副本,你的文件会直接提交到版本库,这通常用在你希望将一组文件加入到 Subversion 版本库时,例如:
$ svnadmin create /var/svn/newrepos
$ svn import mytree file:///var/svn/newrepos/some/project \
-m "Initial import"
mytree/foo.c
mytree/bar.c
mytree/subdir
mytree/subdir/quux.h
Committed revision 1.
The previous example copied the contents of directory&mytree&under the directory&some/project&in the repository:
$ svn list file:///var/svn/newrepos/some/project
Note that after the import is finished, the original tree is&not&converted into a working copy. To start working, you still need to&svn checkout&a fresh working copy of the tree.
Recommended Repository Layout
While Subversion's flexibility allows you to lay out your repository in any way that you choose, we recommend that you create a&trunkdirectory to hold the &main line& of development, a&branches&directory to contain branch copies, and a&tags&directory to contain tag copies. For example:
$ svn list file:///var/svn/repos
You'll learn more about tags and branches in&. For details and how to set up multiple projects, see&&and&&to read more about project roots.
Initial Checkout
Most of the time, you will start using a Subversion repository by doing a&checkout&of your project. Checking out a repository creates a &working copy& of it on your local machine. This copy contains the&HEAD&(latest revision) of the Subversion repository that you specify on the command line:
$ svn checkout http://svn.collab.net/repos/svn/trunk
trunk/Makefile.in
trunk/ac-helpers
trunk/ac-helpers/install.sh
trunk/ac-helpers/install-sh
trunk/build.conf
Checked out revision 8810.
Although the preceding example checks out the trunk directory, you can just as easily check out any deep subdirectory of a repository by specifying the subdirectory in the checkout URL:
$ svn checkout \
http://svn.collab.net/repos/svn/trunk/subversion/tests/cmdline/
cmdline/revert_tests.py
cmdline/diff_tests.py
cmdline/autoprop_tests.py
cmdline/xmltests
cmdline/xmltests/svn-test.sh
Checked out revision 8810.
Since Subversion uses a copy-modify-merge model instead of lock-modify-unlock (see&), you can immediately make changes to the files and directories in your working copy. Your working copy is just like any other collection of files and directories on your system. You can edit and change it, move it around, even delete the entire working copy and forget about it.
While your working copy is &just like any other collection of files and directories on your system,& you can edit files at will, but you must tell Subversion about&everything else&that you do. For example, if you want to copy or move an item in a working copy, you should use&svn copy&or&svn move&instead of the copy and move commands provided by your operating system. We'll talk more about them later in this chapter.
警告因为你的工作副本&同你系统上的文件和目录没有任何区别&,你可以随意修改文件,但是你必须告诉 Subversion 你做的其他任何事。例如,你希望拷贝或移动工作副本的一个文件,你应该使用 svn copy 或者 svn move,而不要使用操作系统的拷贝移动命令,我们会在本章后面详细介绍。
Unless you're ready to commit the addition of a new file or directory or changes to existing ones, there's no need to further notify the Subversion server that you've done anything.
While you can certainly check out a working copy with the URL of the repository as the only argument, you can also specify a directory after your repository URL. This places your working copy in the new directory that you name. For example:
svn checkout http://svn.collab.net/repos/svn/trunk subv 新创建一个subv目录,包含trunk文件。
subv/Makefile.in
subv/ac-helpers
subv/ac-helpers/install.sh
subv/ac-helpers/install-sh
subv/build.conf
Checked out revision 8810.
That will place your working copy in a directory named&subv&instead of a directory named&trunk&as we did previously. The directory&subvwill be created if it doesn't already exist.
Basic Work Cycle
Subversion has numerous features, options, bells, and whistles, but on a day-to-day basis, odds are that you will use only a few of them. In this section, we'll run through the most common things that you might find yourself doing with Subversion in the course of a day's work.
基本的工作循环
Subversion 有许多特性, 选项和华而不实的高级功能,但日常的工作中你只使用其中的一小部分,在这一节里,我们会介绍许多你在日常工作中常用的命令。
典型的工作周期是这样的:
The typical work cycle looks like this:
Update your working copy.
svn update
Make changes.
svn delete
Examine your changes.
svn status
Possibly undo some changes.
svn revert
Resolve conflicts (merge others' changes).
svn update
svn resolve
Commit your changes.
svn commit
Update Your Working Copy
When working on a project with a team, you'll want to update your working copy to receive any changes other developers on the project have made since your last update. Use&svn update&to bring your working copy into sync with the latest revision in the repository:
$ svn update
Updated to revision 2.
In this case, it appears that someone checked in modifications to both&foo.c&and&bar.c&since the last time you updated, and Subversion has updated your working copy to include those changes.
When the server sends changes to your working copy via&svn update, a letter code is displayed next to each item to let you know what actions Subversion performed to bring your working copy up to date. To find out what these letters mean, run&svn help update.
Make Changes to Your Working Copy
Now you can get to work and make changes in your working copy. It's usually most convenient to decide on a discrete change (or set of changes) to make, such as writing a new feature, fixing a bug, and so on. The Subversion commands that you will use here are&svn add,svn delete,&svn copy,&svn move, and&svn mkdir. However, if you are merely 仅仅editing files that are already in Subversion, you may not need to use any of these commands until you commit.
You can make two kinds of changes to your working copy:&file changes&and&tree changes. You don't need to tell Subversion that you int just make your changes using your text editor, word processor, graphics program, or whatever tool you would normally use. Subversion automatically detects which files have been changed, and in addition, it handles binary files just as easily as it handles text files&and just as efficiently, too. For tree changes, you can ask Subversion to &mark& files and directories for scheduled removal, addition, copying, or moving. These changes may take place immediately in your working copy, but no additions or removals will happen in the repository until you commit them.
Here is an overview of the five Subversion subcommands that you'll use most often to make tree changes:
svn add foo 添加foo
Schedule file, directory, or symbolic link&foo&to be added to the repository. When you next commit,&foo&will become a child of its parent directory. Note that if&foo&is a directory, everything underneath&foo&will be scheduled for addition. If you want only to add&foo&itself, pass the&--depth empty&option.
svn delete foo 注意文件和目录不同
Schedule file, directory, or symbolic link&foo&to be deleted from the repository. If&foo&is a file or link, it is immediately deleted from your working copy. If&foo&is a directory, it is not deleted, but Subversion schedules it for deletion. When you commit your changes,&foo&will be entirely removed from your working copy and the repository.&[]
svn copy foo bar
Create a new item&bar&as a duplicate of&foo&and automatically schedule&bar&for addition. When&bar&is added to the repository on the next commit, its copy history is recorded (as having originally come from&foo).&svn copy&does not create intermediate directories unless you pass the&--parents&option.
svn move foo bar
This command is exactly the same as running& svn delete foo. That is,&bar&is scheduled for addition as a copy of&foo, and&foo&is scheduled for removal.&svn move&does not create intermediate directories unless you pass the&--parents&option.
svn mkdir blort
This command is exactly the same as running& svn add blort. That is, a new directory named&blort&is created and scheduled for addition.
Changing the Repository Without a Working Copy
There&are&some use cases that immediately commit tree changes to the repository. This happens only when a subcommand is operating directly on a URL, rather than on a working-copy path. In particular, specific uses of&svn mkdir,&svn copy,&svn move, and&svn delete&can work with URLs (and don't forget that&svn import&always makes changes to a URL).
URL operations behave in this manner because commands that operate on a working copy can use the working copy as a sort of &staging area& to set up your changes before committing them to the repository. Commands that operate on URLs don't have this luxury, so when you operate directly on a URL, any of the aforementioned actions represents an immediate commit.
Examine Your Changes
Once you've finished making changes, you need to commit them to the repository, but before you do so, it's usually a good idea to take a look at exactly what you've changed. By examining your changes before you commit, you can make a more accurate log message. You may also discover that you've inadvertently changed a file, and this gives you a chance to revert those changes before committing. Additionally, this is a good opportunity to review and scrutinize changes before publishing them. You can see an overview of the changes you've made by using&svn status, and dig into the details of those changes by using&svn diff.
Subversion has been optimized to help you with this task, and it is able to do many things without communicating with the repository. In particular, your working copy contains a hidden cached &pristine& copy of each version-controlled file within the&.svn&area. Because of this, Subversion can quickly show you how your working files have changed or even allow you to undo your changes without contacting the repository.
See an overview of your changes
To get an overview of your changes, you'll use the&svn status&command. You'll probably use&svn status&more than any other Subversion command.
If you run&svn status&at the top of your working copy with no arguments, it will detect all file and tree changes you've made. Here are a few examples of the most common status codes that&svn status&can return. (Note that the text following&#&is not actually printed bysvn status.)
# file is not under version control
stuff/loot/bloo.h
# file is scheduled for addition
stuff/loot/lump.c
# file has textual conflicts from an update
stuff/fish.c
# file is scheduled for deletion
# the content in bar.c has local modifications
In this output format,&svn status&prints six columns of characters, followed by several whitespace characters, followed by a file or directory name. The first column tells the status of a file or directory and/or its contents. The codes we listed are:
The file, directory, or symbolic link&item&has been scheduled for addition into the repository.
The file&item&is in a state of conflict. That is, changes received from the server during an update overlap with local changes that you have in your working copy (and weren't resolved during the update). You must resolve this conflict before committing your changes to the repository.
The file, directory, or symbolic link&item&has been scheduled for deletion from the repository.
The contents of the file&item&have been modified.
If you pass a specific path to&svn status, you get information about that item alone:
$ svn status stuff/fish.c
stuff/fish.c
svn status&also has a&--verbose&(-v) option, which will show you the status of&every&item in your working copy, even if it has not been changed:
$ svn status -v 列出所有文件的所有状态
stuff/trout.c
stuff/fish.c
stuff/things
stuff/things/bloo.h
stuff/things/gloo.c
This is the &long form& output of&svn status. The letters in the first column mean the same as before, but the second column shows the working revision of the item. The third and fourth columns show the revision in which the item last changed, and who changed it.
None of the prior invocations to&svn status&contact the repository&instead, they compare the metadata in the&.svn&directory with the working copy. Finally, there is the&--show-updates&(-u) option, which contacts the repository and adds information about things that are out of date:
$ svn status -u -v
stuff/trout.c
stuff/fish.c
stuff/things/bloo.h
Status against revision:
Notice the two asterisks: if you were to run&svn update&at this point, you would receive changes to&README&and&trout.c. This tells you some very useful information&you'll need to update and get the server changes on&README&before you commit, or the repository will reject your commit for being out of date (more on this subject later).
svn status&can display much more information about the files and directories in your working copy than we've shown here&for an exhaustive description of&svn status&and its output, see&.
如果你已经svn commit了,那么svn status没有任何输出。
Examine the details of your local modifications
Another way to examine your changes is with the&svn diff&command. You can find out&exactly&how you've modified things by running&svn diffwith no arguments, which prints out file changes in&unified diff format:
$ svn diff
Index: bar.c
===================================================================
(revision 3)
(working copy)
@@ -1,7 +1,12 @@
+#include &sys/types.h&
+#include &sys/stat.h&
+#include &unistd.h&
+#include &stdio.h&
int main(void) {
printf("Sixty-four slices of American Cheese...\n");
printf("Sixty-five slices of American Cheese...\n");
Index: README
===================================================================
--- README
(revision 3)
+++ README
(working copy)
@@ -193,3 +193,4 @@
+Note to self:
pick up laundry.
Index: stuff/fish.c
===================================================================
--- stuff/fish.c
(revision 1)
+++ stuff/fish.c
(working copy)
-Welcome to the file known as 'fish'.
-Information on fish will be here soon.
Index: stuff/things/bloo.h
===================================================================
--- stuff/things/bloo.h
(revision 8)
+++ stuff/things/bloo.h
(working copy)
+Here is a new file to describe
+things about bloo.
The&svn diff&command produces this output by comparing your working files against the cached &pristine& copies within the&.svn&area. Files scheduled for addition are displayed as all added text, and files scheduled for deletion are displayed as all deleted text.
Output is displayed in unified diff format. That is, removed lines are prefaced with&-, and added lines are prefaced with&+.&svn diff&also prints filename and offset information useful to the&patch&program, so you can generate &patches& by redirecting the diff output to a file:
$ svn diff & patchfile
You could, for example, email the patch file to another developer for review or testing prior to a commit.
Subversion uses its internal diff engine, which produces unified diff format, by default. If you want diff output in a different format, specify an external diff program using&--diff-cmd&and pass any flags you'd like to it using the&--extensions&(-x) option. For example, to see local differences in file&foo.c&in context output format while ignoring case differences, you might run&svn diff --diff-cmd /usr/bin/diff --extensions '-i' foo.c.
Undoing Working Changes
Suppose while viewing the output of&svn diff&you determine that all the changes you made to a particular file are mistakes. Maybe you shouldn't have changed the file at all, or perhaps it would be easier to make different changes starting from scratch.
This is a perfect opportunity to use&svn revert:
$ svn revert README
Reverted 'README'
Subversion reverts the file to its premodified state by overwriting it with the cached &pristine& copy from the&.svn&area. But also note that&svn revert&can undo&any&scheduled operations&for example, you might decide that you don't want to add a new file after all:
$ svn status foo
$ svn add foo
$ svn revert foo
Reverted 'foo'
$ svn status foo
svn revert&item&has exactly the same effect as deleting&item&from your working copy and then running&svn update -r BASE&item. However, if you're reverting a file,&svn revert&has one very noticeable difference&it doesn't have to communicate with the repository to restore your file.
Or perhaps you mistakenly removed a file from version control:
$ svn status README
$ svn delete README
$ svn revert README
Reverted 'README'
$ svn status README
Resolve Conflicts (Merging Others' Changes)
比如,我当前的版本库已经过时,修改了一个文件后,提交:
提示信息很明显了,Blue.java文件已经out of date。说明其他人已经修改了这个文件并且commit的了。
We've already seen how&svn status -u&can predict conflicts. Suppose you run&svn update&and some interesting things occur:
$ svn update
Conflict discovered in 'bar.c'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h) help for more options:
The&U&and&G&codes are
those files cleanly absorbed 吸收changes from the repository. The files marked with&U&contained no local changes but were&Updated with changes from the repository. The&G&stands for merGed, which means that the file had local changes to begin with, but the changes coming from the repository didn't overlap with the local changes.
But the next two lines are part of a feature (new in Subversion 1.5) called&interactive conflict resolution. This means that the changes from the server overlapped with your own, and you have the opportunity to resolve this conflict. The most commonly used options are displayed, but you can see all of the options by typing&h:
- mark the conflict to be resolved later
(df) diff-full
- show all changes made to merged file
- change merged file in an editor
- accept merged version of file
(mf) mine-full
- accept my version of entire file (ignore their changes)
(tf) theirs-full - accept their version of entire file (lose my changes)
- launch external tool to resolve conflict
- show this list
Let's briefly review each of these options before we go into detail on what each option means.
(p)ostpone
Leave the file in a conflicted state for you to resolve after your update is complete.
Display the differences between the base revision and the conflicted file itself in unified diff format.
Open the file in conflict with your favorite editor, as set in the environment variable&EDITOR.
(r)esolved
After editing a file, tell&svn&that you've resolved the conflicts in the file and that it should accept the current contents&basically that you've &resolved& the conflict.
(m)ine-(f)ull
Discard the newly received changes from the server and use only your local changes for the file under review.
(t)heirs-(f)ull
Discard your local changes to the file under review and use only the newly received changes from the server.
Launch an external program to perform the conflict resolution. This requires a bit of preparation beforehand.
Show the list of all possible commands you can use in interactive conflict resolution.
We'll cover these commands in more detail now, grouping them together by related functionality.
Viewing conflict differences interactively
Before deciding how to attack a conflict interactively, odds are that you'd like to see exactly what is in conflict, and the&diffcommand (d) is what you'll use for this:
Select: (p) postpone, (df) diff-full, (e) edit,
(h)elp for more options : d
--- .svn/text-base/sandwich.txt.svn-base
Tue Dec 11 21:33:57 2007
+++ .svn/tmp/tempfile.32.tmp
Tue Dec 11 21:34:33 2007
@@ -1 +1,5 @@
-Just buy a sandwich.
+&&&&&&& .mine
+Go pick up a cheesesteak.
+Bring me a taco!
+&&&&&&& .r32
The first line of the diff content shows the previous contents of the working copy (the&BASE&revision), the next content line is your change, and the last content line is the change that was just received from the server (usually&the&HEAD&revision). With this information in hand, you're ready to move on to the next action.
Resolving conflict differences interactively
There are four different ways to resolve conflicts interactively&two of which allow you to selectively merge and edit changes, and two of which allow you to simply pick a version of the file and move along.
If you wish to choose some combination of your local changes, you can use the &edit& command (e) to manually edit the file with conflict markers in a text editor (determined by the&EDITOR&environment variable). Editing the file by hand in your favorite text editor is a somewhat low-tech way of remedying conflicts (see&&for a walkthrough), so some people like to use fancy graphical merge tools instead.
(我们我们选e编辑文件,需要设定config文件中的:
### Set editor-cmd to the command used to invoke your text editor.### &
This will override the environment variables that Subversion###examines by default to find this information ($EDITOR,&### & et al).
#editor-cmd = editor (vim, emacs, notepad, etc.)
设置为vim:
editor-cmd=vim
选e时就可以打开了。我们设置cofig会重载一起设置的打开的环境变量。
To use a merge tool, you need to either set the&SVN_MERGE&environment variable or define the&merge-tool-cmd&option in your Subversion configuration file (see&&for more details). Subversion will pass four arguments to the merge tool: the&BASE&revision of the file, the revision of the file received from the server as part of the update, the copy of the file containing your local edits, and the merged copy of the file (which contains conflict markers). If your merge tool is expecting arguments in a different order or format, you'll need to write a wrapper script for Subversion to invoke. After you've edited the file, if you're satisfied with the changes you've made, you can tell Subversion that the edited file is no longer in conflict by using the &resolve& command (r).
If you decide that you don't need to merge any changes, but just want to accept one version of the file or the other, you can either choose your changes (a.k.a. &mine&) by using the &mine-full& command (mf) or choose theirs by using the &theirs-full& command (tf).
Postponing conflict resolution 延后冲突解决
This may sound like an appropriate section for avoiding marital disagreements, but it's actually still about Subversion, so read on. If you're doing an update and encounter a conflict that you're not prepared to review or resolve, you can type&p&to postpone resolving a conflict on a file-by-file basis when you run&svn update. If you're running an update and don't want to resolve any conflicts, you can pass the&--non-interactive&option to&svn update, and any file in conflict will be marked with a&C&automatically.
The&C&stands for&conflict. This means that the changes from the server overlapped with your own, and now you have to manually choose between them after the update has completed. When you postpone a conflict resolution,&svn&typically does three things to assist you in noticing and resolving that conflict:
Subversion prints a&C&during the update and remembers that the file is in a state of conflict.
If Subversion considers the file to be mergeable, it places&conflict markers&special strings of text that delimit the &sides& of the conflict&into the file to visibly demonstrate the overlapping areas. (Subversion uses the&svn:mime-type&property to decide whether a file is capable of contextual, line-based merging. See&&to learn more.)
For every conflicted file, Subversion places three extra unversioned files in your working copy:
Subversion 在更新时打印&C&标记,并且标记这个文件处于冲突状态。
如果Subversion认为这个文件是可以合并的,它会置入冲突标记&特殊的横线分开冲突的&两面&&在文件里可视化的描述重叠的部分(Subversion 使用&svn:mime-type&属性来决定一个文件是否可以使用基于上下文的,以行为基础的合并,更多信息可以参见。)
对于每一个冲突的文件,Subversion放置三个额外的未版本化文件到你的工作副本:
filename.mine 我正在编辑的文件。
This is your file as it existed in your working copy before you updated your working copy&that is, without conflict markers. This file has only your latest changes in it. (If Subversion considers the file to be unmergeable, the&.mine&file isn't created, since it would be identical to the working file.)
filename.rOLDREV &当我上次update时获取的文件,就是当我还没修改代码之前的文件。
This is the file that was the&BASE&revision before you updated your working copy. That is, the file that you checked out before you made your latest edits.
filename.rNEWREV 版本库最新的文件。
This is the file that your Subversion client just received from the server when you updated your working copy. This file corresponds to the&HEAD&revision of the repository.
Here&OLDREV&is the revision number of the file in your&.svn&directory, and&NEWREV&is the revision number of the repository&HEAD.
For example, Sally makes changes to the file&sandwich.txt, but does not yet commit those changes. Meanwhile, Harry commits changes to that same file. Sally updates her working copy before committing and she gets a conflict, which she postpones:
$ svn update
Conflict discovered in 'sandwich.txt'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h)elp for more options : p
sandwich.txt
Updated to revision 2.
sandwich.txt
sandwich.txt.mine
sandwich.txt.r1
sandwich.txt.r2
(所有,一旦冲突产生,会有4个文件,一个原来名字的文件,里面包含冲突,另外3个临时文件)。冲突文件类似如:
public class Blue extends Color {
void bepaint(String penType, String name) {
&&&&&&& .mine
//System.out.println(penType+"蓝色的"+name+".");
System.out.lprintLn(penType+"蓝色"+name);
System.out.println('这是新添加的一句');
System.out.println(penType+"蓝色的"+name+".");
&&&&&&& .r4
void addFunc()
System.out.println("addFunc");
(上面的说名:我当前工作版本是r2.但是版本库最新版是r4.我已经落后2个版本了。
和==========之间是我目前所做的修改
==========
和》》》》》》》》》》》》》》r4所做的修改
At this point, Subversion will&not&allow Sally to commit the file&sandwich.txt&until the three temporary files are removed:在这种情况下,Subversion&不会允许 Sally 提交&sandwich.txt,直到这三个临时文件被删除。
$ svn commit -m "Add a few more things"
svn: Commit failed (details follow):
svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict
If you've postponed a conflict, you need to resolve the conflict before Subversion will allow you to commit your changes. You'll do this with the&svn resolve&command and one of several arguments to the&--accept&option.
If you want to choose the version of the file that you last checked out before making your edits, choose the&base&argument.
If you want to choose the version that contains only your edits, choose the&mine-full&argument.
If you want to choose the version that your most recent update pulled from the server (and thus discarding your edits entirely), choose the&theirs-full&argument.
However, if you want to pick and choose from your changes and the changes that your update fetched from the server, merge the conflicted text &by hand& (by examining and editing the conflict markers within the file) and then choose the&working&argument.
svn resolve&removes the three temporary files and accepts the version of the file that you specified with the&--accept&option, and Subversion no longer considers the file to be in a state of conflict:
如果你延迟解决冲突,你需要在 Subversion 允许你提交你的修改之前解决冲突。你可以通过&svn resolve&命令和&--accept&选项的多个参数之中的一个来完成。
如果你希望选择上次检出后修改之前的文件版本,选择&base&参数。
如果你希望选择只包含你修改的版本,选择&mine-full&参数。
如果你希望选择最近从服务器更新的版本(因此会丢弃你的所有编辑),选择&theirs-full&参数。
然而,如果你想在自己的修改与服务器端的修改之间部分选择的话,请&手工&合并冲突文本(检查和编辑文件中的冲突标记),然后选择参数&working&。
svn resolve&删除这三个临时文件,使用&--accept&选项指定的文件版本,从而 Subversion 不会再认为文件处于冲突状态。
$ svn resolve --accept working sandwich.txt
Resolved conflicted state of 'sandwich.txt'
Merging conflicts by hand
Merging conflicts by hand can be quite intimidating the first time you attempt it, but with a little practice, it can become as easy as falling off a bike.
Here's an example. Due to a miscommunication, you and Sally, your collaborator, both edit the file&sandwich.txt&at the same time. Sally commits her changes, and when you go to update your working copy, you get a conflict and you're going to have to edit&sandwich.txt&to resolve the conflict. First, let's take a look at the file:
第一次尝试解决冲突让人感觉很害怕,但经过一点训练,它简单的像是骑着车子下坡。
这里一个简单的例子。由于不良的交流,你和同事 Sally 同时编辑了&sandwich.txt&。Sally 提交了修改,当你准备更新你的工作副本时,冲突发生了,你不得不去修改sandwich.txt&来解决冲突。首先,看一下这个文件:
$ cat sandwich.txt
Top piece of bread
Mayonnaise
&&&&&&& .mine
Mortadella
Prosciutto
Sauerkraut
Grilled Chicken
&&&&&&& .r2
Creole Mustard
Bottom piece of bread
小于号, 等于号和大于号字符串是冲突标记,并不是冲突的数据。你通常要确包这些内容在下次提交之前被删除,前两组冲突标记中间的内容是你在冲突区所做的修改:
&&&&&&& .mine
Mortadella
Prosciutto
后两组冲突标记之间的内容是 Sally 提交的修改:
Sauerkraut
Grilled Chicken
&&&&&&& .r2
Usually you won't want to just delete the conflict markers and Sally's changes&she's going to be awfully surprised when the sandwich arrives and it's not what she wanted. This is where you pick up the phone or walk across the office and explain to Sally that you can't get sauerkraut from an Italian deli.&[]&Once you've agreed on the changes you will commit, edit your file and remove the conflict markers:通常你并不希望只是删除冲突标志和Sally的修改&当她收到三明治时,会非常的吃惊。所以你应该走到她的办公室或是拿起电话告诉Sally,你没办法从从意大利熟食店得到想要的泡菜。[]一旦你们确认了提交内容后,修改文件并且删除冲突标志。
Top piece of bread
Mayonnaise
Mortadella
Prosciutto
Creole Mustard
Bottom piece of bread
Now use svn resolve, and you're ready to commit your changes:
$ svn resolve --accept working sandwich.txt
Resolved conflicted state of 'sandwich.txt'
$ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."
现在我们准备好提交修改了,注意svn resolved不像我们本章学过的其他命令一样需要参数,在任何你认为解决了冲突的时候,只需要小心运行svn resolved,&一旦删除了临时文件,Subversion会让你提交这文件,即使文件中还存在冲突标记。
记住,如果你修改冲突时感到混乱,你可以参考subversion生成的三个文件&包括你未作更新的文件。你也可以使用三方交互合并工具检验这三个文件。
Discarding your changes in favor of a newly fetched revision 放弃你的修改
If you get a conflict and decide that you want to throw out your changes, you can run&svn resolve --accept theirs-full&CONFLICTED-PATH&and Subversion will discard your edits and remove the temporary files:
&如果你只是希望取消你的修改,你可以仅仅拷贝Subversion为你生成的文件替换你的工作拷贝:
$ svn update
Conflict discovered in 'sandwich.txt'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h) help for more options: p
sandwich.txt
Updated to revision 2.
$ ls sandwich.*
sandwich.txt
sandwich.txt.mine
sandwich.txt.r2
sandwich.txt.r1
$ svn resolve --accept theirs-full sandwich.txt
Resolved conflicted state of 'sandwich.txt'
使用svn revert
如果你得到冲突,经过检查你决定取消自己的修改并且重新编辑,你可以恢复你的修改:
$ svn revert sandwich.txt
Reverted 'sandwich.txt'
$ ls sandwich.*
sandwich.txt
注意,当你恢复一个冲突的文件时,不需要再运行svn resolved。
Commit Your Changes
Finally! Your edits are finished, you've merged all changes from the server, and you're ready to commit your changes to the repository.
The&svn commit&command sends all of your changes to the repository. When you commit a change, you need to supply a&log messagedescribing your change. Your log message will be attached to the new revision you create. If your log message is brief, you may wish to supply it on the command line using the&--message&(or&-m) option:
$ svn commit -m "Corrected number of cheese slices."
sandwich.txt
Transmitting file data .
Committed revision 3.
然而,如果你把写日志信息当作工作的一部分,你也许会希望告诉Subversion通过一个文件名得到日志信息,使用--file选项:
$ svn commit -F logmsg
sandwich.txt
Transmitting file data .
Committed revision 4.
如果你没有指定--message或者--file选项,Subversion会自动地启动你最喜欢的编辑器(见的editor-cmd部分)来编辑日志信息。
如果你使用编辑器撰写日志信息时希望取消提交,你可以直接关掉编辑器,不要保存,如果你已经做过保存,只要简单的删掉所有的文本并再次保存,然后退出。
$ svn commit
Waiting for Emacs...Done
Log message unchanged or not specified
a)bort, c)ontinue, e)dit
版本库不知道也不关心你的修改作为一个整体是否有意义,它只检查是否有其他人修改了同一个文件,如果别人已经这样做了,你的整个提交会失败,并且提示你一个或多个文件已经过时了:
$ svn commit -m "Add another rule"
svn: Commit failed (details follow):
svn: Your file or directory 'sandwich.txt' is probably out-of-date
错误信息的精确措辞依赖于网络协议和你使用的服务器,但对于所有的情况,其思想完全一样。)
此刻,你需要运行svn update来处理所有的合并和冲突,然后再尝试提交。
我们已经覆盖了Subversion基本的工作周期,还有许多其它特性可以管理你得版本库和工作拷贝,但是只使用前面介绍的命令你就可以很进行日常工作了,我们还会覆盖更多用的还算频繁的命令。
http://svnbook./en/1.5/svn-book.html#svn.tour.cycle
&http://www./svnbook/1.4/svn.tour.history.html

我要回帖

更多关于 git 撤销commit 的文章

 

随机推荐