Specifically:
Why do I need to explicitly enable "Enable baseless merges" all the time? I am integrating from my branch to the trunk.
What does "Enable integrate over
deleted targets" mean? Shouldn't it
do this by default? If the file
doesn't exist, and you integrate to
that branch with the file, it should
create the file, right??
What does "Do not get latest revision
of selected files" have to do with
integrating? I should be choosing a
source revision, and a target (to
create a new target revision).
What does "Disregard indirect
integration history" mean? I've never used it, since it sounds scary.
I would be grateful to know, as I am a little unsure of what options to enable when I am trying to do various integration tasks from our trunk to various branches or vice versa. (I am not the buildmaster, but hey, I want to know what he knows).
Why do I need to explicitly enable
"Enable baseless merges" all the time?
I am integrating from my branch to the
trunk.
Can't help you here. Something is not right.
What does "Enable integrate over
deleted targets" mean?
If the target file has been deleted and the source file has changed, will re-branch the source file on top of the target file. Without this option, a file on the branch, that has been changed on the branch and deleted on the trunk, would not be allowed to be integrated back into the trunk.
Shouldn't it do this by default?
Not if you are integrating a file back into the trunk, which you branched from the trunk, then deleted on the trunk. Normally 'p4 integrate' avoids mixing outstanding edits with a deleted file. You have to use the advanced options to tell it how to deal with a deleted file.
If the file doesn't exist, and you
integrate to that branch with the
file, it should create the file,
right?
When integrating a file, that previously never existed (i.e., it was added to the branch), from one location to another, yes, Perforce will simply create it in the location into which you are integrating. However, if the file originally came from the trunk, was deleted on the trunk, and now you're trying to integrate it back into the trunk from the branch, you have to tell it what to do via these integration options. Here's the command line switches to which these options correspond:
Enable integrations around deleted revisions = -d
Integrate over deleted targets = -Dt
Delete target file when source is deleted = -Ds
Try to integrate changes when source is deleted and re-added = -Di
You can learn more about them in the integrate command help (type "p4 help integrate" at the command line).
What does "Do not get latest revision
of selected files" have to do with
integrating?
This tells Perforce to use the workspace revision of the target file. By default, the head revision of the target file is automatically retrieved into the workspace before integrating. Say you have made one revision to a branch file and integrated it back into the trunk. The trunk and branch now have two revisions of this file. You submit a change to the branch file so it now has 3 revisions. You sync the branch file back to revision 2. If you were to do a normal integration right now, Perforce would assume you want to integrate everything up to the head revision and would integrate revision 3 of the branch file into the trunk. If you were to select this option, it would say, "all revision(s) already integrated" because you have revision 2 in your workspace. It would be the same as attempting to integrate with the "Limit the range of the integration:" option set to "Integrate all revisions up to:" Revision 2.
What does "Disregard indirect
integration history" mean? I've never
used it, since it sounds scary.
I can't figure out, nor find any info about, what this does.
In general, to merge two files, perforce looks for a "base", the closest revision to the two files, and uses that to provide a much better diff than just directly running a diffing the two files. See Knowledge Base Article. Without knowing your perforce setup, I couldn't say what was going wrong, however, p4win has some nice graphical tools to visualize branches, you might be able to determine why perforce can't find a base for you. This is also what "Disregard indirect integration history" does: stops it from looking for the base.
For the "don't sync to head": when integrating, your "target" is the files in your local client, which you aren't specifying a revision for; instead, perforce will either sync your revision head (if you don't use "-h"), or will use the one you currently have. You can't specify an arbitrary revision because your local client only has a particular one.
"Enable integrate over deleted targets" can lead to problems if done blindly. Here's an example: Imagine you refactor your code in your next release branch, and eliminate a source file as a result - the functionality was merged into some other source files. You then fix a bug in that original source file in a maintenance branch for the previous release. If you integrate over delete by default, the dead source file comes back, but it won't be built and the bug wouldn't have been fixed. It'd better to be warned that this occurred so you could manually merge the fix into the other source files.
Related
My team is supporting a small Java development team that had been working on a development branch with Eclipse and Subclipse. We've been periodically merging their changes associated with appropriate tasks and defects from this development branch to a release branch which eventually gets merged into a trunk that represents production. Based on best practices advice from CollabNet, we recently created a new development branch from the trunk and moved the old development branch to an archive directory. (The motivation for this is that eventually changes would accumulate in the development branch that never get merged anywhere else, and the development branch would become impractically different from the release branches and the trunk.)
Our java team was disappointed to discover that once they'd created their new Eclipse workspaces with the new development branch, file histories in Subclipse did not show all of their individual changes. Only the merge operations are listed. This makes sense since the new development branch was copied from trunk, which only ever had these merges performed on it.
But our Java team would like to easily reference the histories in the old development branch. What is the easiest way for them to do this? Some options I can think of are:
Navigate to the old branch in the SVN Repository Exploring perspective and examine file histories there. This involves lots of clicking through the repository hierarchy, especially to an individual source file. Is there a way to enter a path in this perspective and jump to it? Or is the only way to click through the hierarchy?
Maintain a separate Eclipse workspace with the old development branch. This means switching workspaces to see the individual developer histories. And it's easy to forget which workspace you're in.
Use Team -> Switch to temporarily switch the file or project to the old branch in your same workspace. Then view the history of the switched file(s). It's easy to forget what you've switched, which can lead to committing to the wrong branch.
Also, none of these options make it easy to compare what's in the new branch to what's in the old branch.
Are there any easier ways I'm missing? Thanks a bunch!
If you really want to follow best practices then you should look at trunk-based development. https://trunkbaseddevelopment.com
There is an option with svn log to show the original commits for a merge. This is the -g option when using the command line. In Subclipse, it is a checkbox on the History view. "Include Merged revisions". This will then expand the merges to show what was merged. Same option exists on Blame. It will make these operations take considerably longer to run in many cases.
The only way to fix this is to use a better process.
I'm coming late to the DVCS party after developing solo for a long time by doing my own version control with copies of folders. For a small project, I would have essentially a folder structure that looked like this:
project
development
release1.0
release1.1 (for a bug fix)
release1.2 (for a bug fix)
release 2.0 (for a new feature)
I'm now getting on board and learning DVCS using Mercurial (SourceTree) and BitBucket, and slowly learning the ropes with both the GUI and command line with some new projects where I could start fresh using DVCS. I'd like to move some of my old projects into DVCS, but I don't want to lose my project history. What is the best path to follow, or is it even worth the effort?
I'm thinking something along the lines of the following (attempting to use an HgFlow methodolgy):
Create repository using code from release 1.0
Commit files into the development branch
Add tag for release1.0
Merge into the master
From the development branch, create feature/hotfix branch for release 1.1
Copy files from release 1.1 into hotfix branch and commit
Merge hotfix branch into develop and master
Add tag for release 1.1
From the development branch, create feature/hotfix branch for release 1.2
Copy files from release 1.2 into hotfix branch and commit
Merge hotfix branch into develop and master
Add tag for release 1.2
etc.
Does this seem like a workable approach? What suggestions do you have?
Yes, your approach is good. The only thing to add it to use hg addremove before you commit the next version of your code. This command can find renamed files for you and will thus help you recreate an even more accurate history.
The workflow then becomes
Create repository
Copy files from release1.0 into the working copy. They will all be seen as unknown (? ... lines in hg status).
Use hg addremove to schedule them all for addition. Adjust the .hgignore file to exclude build output before running hg addremove.
Commit and tag this as 1.0.
Delete all files from your working copy using your normal OS delete command. The files will now be listed as missing (! ... lines in hg status).
Copy files from the release1.1 into the working copy. Files that were changed compared to release1.0 now show up as modified and (importantly) newly added files show up as unknown while removed files still show up as missing.
Run hg addremove to schedule the new files for addition and the missing files for removal. If a file foo.c in 1.0 was renamed to bar.c in 1.1, foo.c will show up as missing and bar.c will show up as unknown. When you run hg addremove, Mercurial will recognize this as a rename. Use the --similarity option to adjust how similar the files need to be for them to be considered a rename.
Commit and tag this as 1.1.
Now repeat for the other releases. The important part is to clean the working copy between each code import — what way you make sure that each commit accurately reflects the state in the folders you used before.
I've just started using subversion, and have read the official documentation (svn book), cheat sheet and a couple of guides. I know how to install subversion (in linux), create a repository (svnadmin create), and import my Eclipse project into the repository (SVN import), view the repository files (using svn list).
But I am unable to understand some of the other terminologies. For example, after importing my Eclipse project into the newly created repository I have made changes to my Eclipse project (more than 1 file). Now, how should I update the repository with this added files/changes made to my Eclipse project?
The svn update command brings the changes from the repository into your working copy - which is the opposite of what I want i.e. bring the changes I made in my Eclipse project into the previously imported project in repository. If I am correct, you update the repository more often (as you keep extending your project implementation) than your current project (with update).
Also, I do not understand when would you use svn merge. The svn book states it applies the differences between 2 sources to a working copy. Is there a scenario which would explain this?
Finally, can I have more than 1 project checked into the repository? Or is it better to create a new repository for each project?
The term you are looking for is "commit".
Subversion does not exclusively lock a file for editing (though there is a command to do this if you really, really want to). So it is possible that you will need to merge two different users' sets of edits on a file, or even edits from two different working copies in two different locations on your machine.
Multiple projects is fine. Best approach IMHO is repository/project/trunk etc rather than repository/trunk/project.
Three things about SVN you should know:
Trunk - The main version of your code
Tags - 'Tagged' Versions of your code (i.e. v1.2.5-release)
Branches - Forks of the code for divergent development paths. We typically fork new branches to work on different versions, so if the current version is 1.2.4, you'd branch for 1.3's development. So if emergency changes to 1.2 need to be made (i.e. 1.2.5) you can work on it without worrying about what you broke by refactoring / feature adding in your 1.3 branch. The merge operation is designed so you can merge 1.3's branch back into trunk when you're ready to release 1.3, or a similar operation. You can also merge individual files (if two or more developers edited the same file at the same time and now you need to 'merge' the changes into the same file.
Each project in your repository should have 3 folders in it:
/trunk
/branches
/tags
These house the three points above. You don't have to have these folders, but you should. Other more mature VCS like Mericual/Git have the concepts of tags and branches baked into the system. In SVN these are more of a convention/reccomendation.
Terminology
Working Copy - The copy on your hard-drive, that contains all your edits, etc...
Add - Registers a file for tracking in version control
Update - Updates the working copy with changes from the server repository
Commit - Updates the server repository with changes from the working copy
Switch - Replaces the working copy with another folder within the server repository
Diff - Does a differential analysis of two files / versions of a file to see the changes between them.
Merge - Attempts to apply the changes from one or more files into another, highlighting conflicts.
Patch - A set of differences that can be used to update a file.
You commit changes to the repository
Merge is useful when you need to maintain two branches of a repository. For examples v1.x with most recent security fixes and the alpha version 2. That allows you to make the fixes in the 1.x code, whith the resulting binary for existing customers, and you can merge the changes into version 2 so fixing the bugs that weren't already caught.
I suggest you look around for 'typical svn workflows'. They will give you the big picture of the 'most common tasks'.
What you want to do is 'commit' the changes made to your files to the repository.
You need to merge in case of a conflict (when 2 or more people are working on a project and commit to the same repo. conflicts might arise).
Check the available articles on SVN kai remember to read about the sample/typical workflows or working scenarios with SVN.
Fully agree with David, but as far as question 3 is concerned, personally, I would distinguish between use cases:
Production: One project per repository. And do get warm with the mentioned tag/trunk/branch concept, it really helps a lot
Testing: I have one single repository where I have put virtually all my experimental codes (approx. 10 languages with x codes per language). Reason is: One experimental code takes me 1-2 minutes, creating a repository on a remote host, using ssh-security sometimes takes longer ;-)
Cheers
EL
I am trying to merge my development branch back into the trunk of my repo. Steps I took:
Switch to trunk
check that it is up to date, resolve any conflicts
Go to Team->Merge
Select URL : development branch
Start Revision: Revision when branch was created
End Revision: HEAD
OK
This should do the magic - it opens up the syncronize view which is fine, shows me all the conflicts, but there the problem happens:
In the compare editor I see two files:
Local File | Remote File (306)
This is really strange, the revision number of the remote file is actually the one of the file in the working copy (trunk) and so is the content. The local file has the content of the file in the branch.
Now the arrow shows correctly that I am merging from left to right (branch to trunk). This also happens when I click ok.
BUT I can only move changes from right to left!!! That's not what I want - I do not want to overwrite the changes in the branches with the old content of the trunk. I want to move the content from left (branch) to right (trunk). But I can't even write in the right file.
I do not know why it writes remote file there?? It's clearly showing the working copy file in the remote file window, and the file from the branch (for merging) is shown in local file.
Some bug in Subversive?
Thx,
Martin
Merges are never been easy with subversive (as mentioned in this old SO question), so may be doing the merge externally (or with subclipse) would be easier here.
If your client and repository are both at least in SVN1.5, Subversive new merge capabilities are better, but still dangerous as illustrated by this thread.
Since Subversive has been modified for SVN 1.5 the whole merge behavior has changed. One thing I really liked is the ability to choose what changes I wanted, apply that to my working copy and then commit to trunk.
Subversive now no longer does that but forces all changes onto your working copy and then you choose what to put in the trunk.
This is not only undesirable behavior but it's also dangerous (if you ignore the possibility of a revert anyway). I prefer to commit things I know work. We have a release branch which gets changes which may or may not need to be migrated to the trunk.
Well this seemed mysterious at first, now I shall provide a decent stab at updating this answer for everyone. This regards merging using the SVN Subversive client for Eclipse:
You are doing your merge correctly, starting in Trunk and then pointing to your file under your local Branch. Your files open up in the "Text Compare" window under the Team Synchronizing tab. If you do not see conflicts over in the left hand navigation column, then your merge has just happened. Yes, this is confusing and non-intuitive.
What the Text Compare window offers you is the ability to undo your change (or any others that may have gotten into your merged file unawares) before you commit it. Remember that you are pulling in the file from Branch, so the idea is that the Branch file is in Trunk but in a kind of virtual limbo until finally committed, and changing or undoing unwanted changes here references the file in Branch (obviously). That is why you only have a one-way pipe (Trunk to Branch) to overwrite those changed merged into Trunk via your working copy. Your merge has taken place, but it's not quite official yet.
If all looks as it should, right click the file in the navigator window (left pane in my Eclipse Helios install) and choose Accept from the drop-down. Then click back over to your main code-viewing tab (in my installation it's PHP but it could be whatever you are using) and then commit the file to Trunk.
If you want to test this, do a view of the file "as is" in Trunk before committing and you should see your changes reflected there if you have done your merge correctly. This appears to be the way it is working for me on an OSX Snow Leopard Macbook Pro. Not sure if it's the same for Windows or Linux folks. I assume it's essentially the same/similar process.
it's easy
check out trunk with check out as... give a different project name.
Now you have both locally as working copy, trunk you wanna commit to and the branch you are working on and whose changes you have comitted to the repository.
Now rightclick the trunk project (and I mean the project, not single files) - merge - select the branch project (again, PROJECT)
accept all changes to local copy
commit what you need to trunk as used to
all fine, delete trunk again and keep working on the branch
especially with branches this seems super easy and worked like a charm for me
Let's say I have committed some bad changes to Subversion repository. Then I commit good changes, that I want to keep.
What would be easiest way to roll back those bad changes in Eclipse, and keep the good changes? Assuming that files relating to bad changes are not same as those relating to the good changes. How things change if good changes were made to same files as bad changes?
I am mostly looking a way to do this via Eclipse plugins (Subclipse or Subversive) but commandline commands are also interesting.
In Eclipse Ganymede (Subclipse)
Select project/file that contains bad change, and from pop-up menu choose:
Team -> Show History
Revisions related to that project/file will be shown in History tab.
Find revision where "bad changes" were committed and from pop-up menu choose:
Revert Changes from Revision X
This will merge changes in file(s) modified within bad revision, with revision prior to bad revision.
There are two scenarios from here:
If you committed no changes for that file (bad revision is last revision for that file), it will simply remove changes made in bad revision. Those changes are merged to your working copy so you have to commit them.
If you committed some changes for that file (bad revision is not last revision for that file), you will have to manually resolve conflict. Let say that you have file readme.txt with, and bad revision number is 33. Also, you've made another commit for that file in revision 34. After you choose Revert Changes from Revision 33 you will have following in your working copy:
readme.txt.merge-left.r33 - bad revision
readme.txt.merge-right.r32 - before bad revision
readme.txt.working - working copy version (same as in r34 if you don't have any uncommitted changes)
Original readme.txt will be marked conflicted, and will contain merged version (where changes from bad revision are removed) with some markers (<<<<<<< .working etc). If you just want to remove changes from bad revision and keep changes made after that, then all you have to do is remove markers. Otherwise, you can copy contents from one of 3 files mentioned above to original file. Whatever you choose, when you are done, mark conflict resolved by
Team - Mark Resolved
Temporary files will be removed and your file will be marked changed. As in 1, you have to commit changes.
Note that this does not remove revision from revision history in svn repository. You simply made new revision where changes from bad revision are removed.
You have two choices to do this.
The Quick and Dirty is selecting your files (using ctrl) in Project Explorer view, right-click them, choose Replace with... and then you choose the best option for you, from Latest from Repository, or some Branch version. After getting those files you modify them (with a space, or fix something, your call and commit them to create a newer revision.
A more clean way is choosing Merge at team menu and navigate through the wizard that will help you to recovery the old version in the actual revision.
Both commands have their command-line equivalents: svn revert and svn merge.
If you want to do 1 file at a time you can go to the History view for the file assuming you have an Eclipse SVN plugin installed. "Team->Show History"
In the History view, find the last good version of that file, right click and choose "Get Contents". This will replace your current version with that version's contents. Then you can commit the changes when you've fixed it all up.
In Eclipse using Subversive:
Right click your project > Team > Merge
In the merge window, select the revisions you want to revert as normally but also enable checkbox "Reversed merge".
Merge as normally.
I have written a couple of blog posts on this subject. One that is Subclipse centric: http://markphip.blogspot.com/2007/01/how-to-undo-commit-in-subversion.html and one that is command-line centric: http://blogs.collab.net/subversion/2007/07/second-chances/
The svnbook has a section on how Subversion allows you to revert the changes from a particular revision without affecting the changes that occured in subsequent revisions:
http://svnbook.red-bean.com/en/1.4/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.undo
I don't use Eclipse much, but in TortoiseSVN you can do this from the from the log dialogue; simply right-click on the revision you want to revert and select "Revert changes from this revision".
In the case that the files for which you want to revert "bad changes" had "good changes" in subsequent revisions, then the process is the same. The changes from the "bad" revision will be reverted leaving the changes from "good" revisions untouched, however you might get conflicts.
I have same problem but CleanUp eclipse option doesn't work for me.
1) install TortoiseSVN
2) Go to windows explorer and right click on your project directory
3 Choice CleanUp option (by checking break lock option)
It's works.
Hope this helps someone.