Clearcase: how to copy/fork a file? - clearcase

In Clearcase, I want to copy (fork, split) a file while preserving its history. Something like svn cp old.txt new.txt. How do I do it?

It isn't possible do fork a file in ClearCase.
If you refactor your code and split a file in two, one of them will appear as a new file and you will loose the information about who coded it. The annotate command will say the author of the lines are who splited it.

UCM or not, you cannot duplicate easily the full history of a file.
The best way to isolate an history is still to create a branch in order to make new versions to that file without impacting the same file in the original branch.
Thinking 'svn cp' should be available in ClearCase might come from the fact that, in SVN, branches are directories, and a tool like cc2svn will actually replicate ClearCase branches using 'svn cp'.
But since, with ClearCase, branches are first-class citizen, it is best to reason in term of branch than in term of copy/fork.
From the main page of cc2svn:
There is a difference in creating the branches in ClearCase and SVN:
SVN copies all files from parent branch to the target like: svn cp branches/main branches/dev_branch
ClearCase creates the actual branch for file upon checkout operation only.

Pretty simply done
Check out parent folder
Move element you wish to duplicate to appropriate location (not within the checked out parent folder)
Undo Checkout of parent folder
All the files get returned to the original folder with history and also the duplicate ones remain in the new location with the history too. Now each file can be checked out and changed individually

Related

Get files and directories affected by commit

I want to get list of files and directories affected by specific commit. I have no problem getting the commit itself but I rather don't know how to get affected files and directories.
Just to make it clear I need something like this:
file x - deleted
file y - added
file z - modified
Git is snapshot-based; each commit includes a full list of files and their state. Any notion of "affected" files needs another commit to compare it to. This is commonly done against its parents, which seems to be what you're asking about. You can figure out which files are different between two commits (or more exactly, their trees) by using the git_diff family of functions.
You can find an example of doing so in the examples listing for libgit2. There is also a more general annotated diff example. The second link also shows how to list individual files as well as their contents, if you need that. Check the reference for a a full listing of available function to work with diffs.
Note that this won't give you affected directorires by itself, as Git does not track directories, but only files.
You're looking for git diff.
The same function exists in libgit2, and the documentation for it is here.
If you're analyzing older commits, "git diff [commit1] [commitAfterCommit1]" will give you a list of changes that the second commit made from the first. You could prune this output to get yourself just the changed file names.

Merge all files from a branch into main(using a command/script) cleartool

I want to merge all files from a particular branch to main using a script or a command. Is there a way to do it without checking out each file in target or should i do each file manually.
ClearCase is file-based, not repository-based: any merge will be done file by file, and actually first folder by folder (you merge the folders first, then the files).
The easiest way to initiate a merge based on a branch is to use the cleartool findmerge, which can use a version selector, like -fve/rsion .../branch1/LATEST.
See also "To prepare to merge"
The usual approach though is to use a view or a tag to select the elements you want to merge, as I described in "How merge sub branch to main branch using clearcase command line under linux?" (using -ftag).
Note that this works also in an UCM environment, based on activities (even though the deliver and rebase commands remain the recommended merge methods).

Accessing an eclipsed element in ClearCase

In my current working environment, I make use of eclipsed files extensively for testing purposes. When it comes time to formalize things, I have a script which generates a diff by comparing the file with a backup saved by my eclipse script.
I'd like to be able to work without the backup of the original file; is there any way I can retrieve the current version of the file that I can pass to diff? Even though the file is view-private, I see I can enter foo##/ and see a list of versions, but I'm not sure how to find which version is the latest. Everything I've tried using cleartool ls or describe with the file name tells me that it's not a VOB object (which is true, although cleartool ls does show it as eclipsed, so it must know, somehow, that there is an element there)
Thanks
Eclipsed file means dynamic view.
The simplest solution would to make a second dynamic view based on the same config spec.
Considering how cheap and quick those views are, this isn't an issue.
On that second dynamic view, you can do a
cleartool descr -fmt "%Xn" /path/to/element
In order to get the extended pathname of the file (see fmt_ccase for more on the %Xn syntax).

ClearCase: Files in 2 branches obscure each other

I have checked in the same file (filename) twice in 2 different branches (say, development and release).
This breaks just about anything, so I want to take 1 version and "properly" copy/merge it to the other branch, later merging in the lost changes manually (from a backup). Then I would lose history for 1 file but at least the 2 files would be connected again.
How to do it?
Also note, since the connection is broken, I cannot mere, also, when doing a Version Tree, both files have different version trees. (It is not 2 views at different files in 1 Version Tree, like is the normal/correct case.)
Also, I assume the problem is with the folder having some kind of a reference to 2 different files, but somehow, I cannot edit the folder?!
Those are call "evil twins" (also described in that SO question)
(one less thing to worry with Git ;) )
The easiest way is to pick one branch:
remove the file from the other branch (rmname),
and to the merge.
The merge will add that same file in the other branch.
That process (rmname + merge) is illustrated in "Clearcase: How do I merge in a specific file from one view, into another, to avoid the Evil Twin scenario?"
(edit by Andreas)
Your solution worked great, I changed it for me since I noticed I have a specific case:
The file got bad since someone else renamed it... so it was not just as simple as your solution, but I had to do it "by hand", as is
Go to X:\FullyQualifiedPath (correct path in VOB)
Use:
cleartool ln FullyQualifiedName ./FileName
where FullyQualifiedName is the name as you get it e. g. from VersionTree when you say “Send To -> Copy” (something like //view, drop the file: before). This creates the link
Afterwards, you can see the desired version in the ClearCase Explorer again.

In Mercurial, how do I pick specific files from a named branch to merge back with default?

I have a big named branch with a lot of changes. Some of these changes are non-destructive so I want to pick these specific files out first, and merge them with default as soon as possible. (Then later, the destructive changes are merged as well.)
In Git I would create another branch and squash all changesets outside of the index, then I would add the specific files to the index and commit. After that, I could merge this temporary branch with master so master has a clean commit with only the non-destructive change. I don't know how to do this with Mercurial.
You can use hg cat to grab the contents of a file as it exists on any particular branch, and replace the working copy version with that.
This isn't technically a merge, but since you're replacing whole files you shouldn't have too much of a bad time merging things later:
for example, to grab myfile.c form branch somefeature, and replace the working copy version, do:
hg cat path/to/myfile.c -r somefeature > path/to/myfile.c
note that this completely replaces the working copy file so make sure you have no outstanding changes first
I think mercurialqueues is what you want. With mq you can turn any changeset into a patch and any patch into a changeset. So taking a changeset converting it to a patch deleting the chunks out of the patch that you don't want and then applying it to whatever branch you want. This is a fairly complex operation though and requires a certain amount of discipline on your part. So I would try to nail down your workflow on a test repo before trying it on code you care about.
As far as I know, Mercurial doesnt any have tools to split changesets. If youre lucky, all the changes you want are in separate changesets and then you can use the TransplantExtension. I think it can be compared to Git's cherry-pick but I havent used git much.
You can also use hg diff to manually commit the changes to a certain file to a new branch. Use the rev range to mark your entire source branch:
hg diff myfile -r startrevision:endrevision
The output can be treated as a patch. Do this for each file you want and commit them and then merge. Skipping the destructive changes. You can also, of course, do this multiple times of a destructive change is in the middle of a revision range.
Having said that what youre trying to do isnt something mercurial was built for. That hardcore history editing is more Git's area (note that its just my opinion). Keep your stable changes and destructive changes in separate changesets (and maybe even in separate branches). I use transplant, rebase and strip to move changes around. When its all done, they are merged and properly pushed.
Oh, and check MercurialQueues. I havent used it myself but Ive seen it do some crazy stuff. Maybe its capable of doing something along the lines of what you want.

Resources