Apply local move using 'cm' - plasticscm

Using the PlasticSCM command line cm tool how do I "apply" a local move detected by cm status --localmoved?
By "apply" I mean "change the items status from localmoved to moved so that a subsequent cm ci -c "moved some files" will commit the move.
Things I've tried:
cm co newfile which complains that the file is private.
cm co oldfile which complains that the file does not exist.
cm add newfile which "breaks" the move and turns it into an add and a local delete.
cm mv oldfile newfile which complains that the file does not exist.

Unfortunately there is not a command line option to apply a local moved, but there is a hacker option in the move command that could help here:
cm mv src dst --nomoveondisk
This switch just move the file in the source control, but not on disk. Then your item should appear as moved. Hope it helps.
Update
If you want to checkin that changes, you might use the documented option --applychanges in the checkin command:
cm ci --all --applychanged
This option will apply local changes first, and then will checkin changes to Plastic SCM server.

Related

Perforce unshelve command is not returning the shelved CL's changes

I have written a jenkins script to unshelve perforce changelist and then run commands on it.
p4 -c %my_client_name% unshelve -f -s %SHELVED_CL1% %perforce_path%
this when runs gives me a notification that
- "unshelved, opened for edit"
but, when i check the file, it does not have those shelved CL's changes.
Can anyone tell me why this is happening..
I can think of two possible explanations:
1) You're looking at the wrong local file. Run "p4 -c CLIENT where FILE" to see the mapping for that file, and then look at that local path on the machine where your script is running.
2) The unshelve operation gave you some extra info/warning/error that your script is eating (or that you omitted from your question because it didn't sound relevant). Likely messages would include something along the lines of must resolve #=SHELVED_CL or unable to write LOCAL_FILE. If you got a must resolve message it means the file is already open with local changes and you need to run p4 resolve to merge the local changes with the shelved changes. If there was an error about being unable to write the file the error will probably include an explanation in the form of an OS message (access denied, no permission, etc). As a rule of thumb, if there's some sort of error message, you should figure out what it means and then fix the thing it's complaining about.

tfs/tf.exe: print currently checked out version

I used tf.exe to get a particular version of a source tree like:
$ tf get $/[PATH]/[SUBPATH] /r /version:C1234
Now I want to check the last checkin, but only up to the version as checked out. I tried:
$ tf history . /r /noprompt /stopafter:1 /version:1~W
However, this prints the tip of the source tree as in source control.
Changeset User
--------- ----------------
1555 domain\[USER]
Is there a command option to only show the history of the tree as it is checked out (excluding any changes that may exist on the server, but are not checked out locally), i.e. for the example above, the output should be
Changeset User
--------- ----------------
1234 domain\[USER]
Thanks
Turns out that the command above works after I re-get the workspace but also undid all local changes. In my previous attempt I had kept two local edits (answered "Keep Local Version" to the conflict resolution prompt). Looks like this caused the history command to return the latest server version.

Command line "get latest" from TFS without mapping workspaces and such

I assume that this:
tf.exe get $/project /recursive
...needs this weird workspace mapping, known TFS server and such.
Is there any way I could do this simplest thing: go connect to this TFS server using this set of credentials, get latest source code for this project and put it here? All from the command line.
Firstly, are you wanting a copy of the controlled files that are no longer under source-control (such as a SVN export) or are you still hoping to work with the files and TFS?
Option 1: No Binding at all
If you simply want a copy of the latest files and no 'binding' to TFS, you're going to have to do a little work yourself. Leaving aside credentials ([/login:username,[password]] parameter to many command line methods).
Use the TF command to get a list of the files: tf dir "$/YourSolution" /Recursive > files.txt
Process files.txt with some clever batch file (or use a scripting language):
Read lines starting with $/ and this is the directory, create the directory in your destination (remove first three characters and the last character, a colon).
Read the next lines (until blank or end of file), each of these represents a file in the directory discovered in step 3. Assuming you have the file in a variable %file% and directory %dir%, then issue the following command (for each file in that directory):
tf view "$/%DIR%/%FILE%" "/output:Your-Target-Path/%DIR%/%FILE%"
or if you're happy with the current directory as the target:
tf view "$/%DIR%/%FILE%" "/output:%DIR%/%FILE%"
Note, you need the %DIR%/%FILE% in the output part or all files will be dumped in to the same directory.
NOTE: this is likely to a be VERY high bandwidth and slow operation!
Option 2: Temporary Mapping
Create a temporary workspace: tf workspace /new /collection:<URL_TO_SERVER> /permission:Private (note, this will prompt, there is a no-prompt option but determining a name for the workspace is left as an exercise)
Make a directory for files, e.g. LOCALDIR
Create a mapping for your folders: tf workfold /map "$/SERVER_DIR" "LOCALDIR"
Go into LOCALDIR
Get the files tf get . /Recursive
At this point you should now have all of the files and if you wanted you also have a binding with TFS so you could commit changes. Alternatively, you can now copy the content elsewhere and break the mapping/workspace. Using the correct command line variants of tf workfold /unmap and tf workspace /delete will unmap your workfolder and delete the workspace.
Export any folder cleanly from TFS? Finally found a brilliant solution I think.
I am not going to completely research this for you now, but intend to replace my incredibly messy build server workspace synch script with this later, when I get the time.
Solution:
Use Microsoft's Git-TF to get the source to disk without having to set up a workspace or anything. I tried the command, and it worked wonderfully. Think it will work for TFS 2010 and 2012. From what I can understand, there will be no bindings or workspaces or anything left behind that will cause problems later. I think all you need to install is GIT and GIT-TF.
http://www.microsoft.com/en-us/download/details.aspx?id=30474
You will actually get the files into a GIT repository, which is not a problem at all. You will get a (hidden?) folder named .git inside the folder you exported, and I guess you can simply delete it to get rid of any trace of GIT.
If someone implements this, which should be easy, please confirm it works as expected.
Quick solution
Building on Ray Hayes option 2 answer, I put together an actual script that should be straight forward to use for those who just want the quick and dirty solution. You should read his aswer for more info.
To use it:
Set the four variables to your working environment
remember that your
tf.exe might not be located in the same directory that I have it in,
especially if you are reading this from the future :)
.
SET COLLECTION_URL="http://localhost:8080/tfs/<collection>"
SET SERVER_DIR="$/<REMOTE_SOLUTION_DIR>"
SET LOCAL_DIR="X:\<YourLocalDir>"
SET TF_DIR="C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE"
%TF_DIR%\tf workspace /new /collection:%COLLECTION_URL% /permission:Private /noprompt tmp_batchws
%TF_DIR%\tf workfold /map %SERVER_DIR% %LOCAL_DIR%
cd /d %LOCAL_DIR%
%TF_DIR%\tf get . /Recursive
%TF_DIR%\tf workspace /delete tmp_batchws /noprompt
i wrote the powershell for the leading answer
$base = "f:\whereyouwantthefilestogo\"
foreach($l in get-content D:\outputfromTFdir.txt)
{
if($l -match '^\$.*\:$')
{
$repopath = $l.trim(':')
write-host 'base path'
$basepath = "$base$($l.Substring(2,$l.Length -3) -replace '/','\')"
if((Test-Path $basepath) -eq $false)
{
write-host 'making directory'
New-Item -ItemType directory -Path $basepath
}
continue;
}
elseif($l -match '^\$')
{
write-host 'sub folder'
$subfolderpath = "$basepath\$($l.trim('$'))"
if((Test-Path $subfolderpath) -eq $false)
{
write-host 'making directory'
New-Item -ItemType directory -Path $subfolderpath
}
continue;
}
elseif($l -match '.*\..*')
{
write-host 'get file'
$filename = "$basepath\$l"
write-host $filename
$repofile = "$repopath/$l"
tf view "$repofile" "/output:$filename" /collection:http://tfsserver
}
else{write-host 'blank line'}
}
There is no "easy" option when it comes to TFS command lines - they almost always involve an awful lot of typing (such as not being able to simply have a default set up so you don't have to specify a collection URL on every command)
The usual way to make TFS command lines "simple" is to write batch files to hide away all the details that have to be specified every time (server URLs and recurse flags etc)
TF.exe does allow you to do almost anything, though, so it is a pretty straight-forward sequence of tf calls to create a temporary mapping, do a Get and and delete the mapping again.
http://johannblais.blogspot.com/2014/07/tfs-equivalent-of-svn-export.html
http://tfs-server:port/tfs/Collection/TeamProject/Team/_api/_versioncontrol/itemContentZipped?repositoryId=&path=url-encoded-source-control-path
tfs-server is the TFS server hostname
port is the TFS port (usually
8080)
Collection is the name of your team project collection
TeamProject is the name of your team project
Team is the name of the team
url-encoded-source-control-path is the URL encoded source
control path (for example, $/Project1/Main/Sources/Folder/SubFolder becomes %24%2FProject1%2FMain%2FSources%2FFolder%2FSubFolder

Team Foundation Server switch between branches

Can we switch between branches in TFS
what i want is i downloaded a working copy and now I want to switch to different branch without downloading everything, because for large projects it will take lot of time since developers spend lot of time downloading
Is it possible, if not any workaround ??
You can switch branches from the command-line client (only downloading the differences) by changing your workspace mappings and using the /remap flag to the get command:
tf workfold /map $/Branch1 C:\Work
tf get C:\Work /version:T /recursive
tf workfold /unmap $/Branch1
tf workfold /map $/Branch2 C:\Work
tf get C:\Work /remap /version:T /recursive
In TFS branches are "physically" present in the Source Control, they're like "special folders". So you can totally choose what branch you get locally by targeting the right folder for your get.
If you have for instance:
Projects [folder]
ProjectA [folder]
Dev [Branch]
V1 [Branch]
ProjectB [folder]
Dev [Branch]
V1 [Branch]
and you want to get at the "Projects" level with only the content of "Dev", you can create mapping in your Workspace definition to cloack the V1 branches of ProjectA and B.
Just for supplementing the knowledge base - my colleague Isak Savo created useful batch for such purpose. You need to do some editing inside the script (at the top) to point to the correct source code location and appropriate branches. The core is basically the same as in Edward Thomson answer, but with some interactive logic added. I made some minor changes (directory context switching for tf commands, quotes for arguments - needed if there are spaces in directories) and shared it below:
#echo off
rem Command to switch the current source tree to a new branch.
rem It's best to not have any pending changes.
set DEVBRANCH=$/dir/src1
set RELEASEBRANCH=$/dir/src2
set SOURCEDIR=c:\sources directory\src
if exist "%SOURCEDIR%" goto ASK
echo Source code directory (%SOURCEDIR%) not found, please edit this script to point to the correct directory
pause
exit
:ASK:
set TARGET=
echo Available branches are:
echo Dev: %DEVBRANCH%
echo Release: %RELEASEBRANCH%
set /P ANSWER=Specify target branch? [Dev, Release]
cls
if /I "%ANSWER%"=="Release" set TARGET=%RELEASEBRANCH%
if /I "%ANSWER%"=="Dev" set TARGET=%DEVBRANCH%
if /I "%ANSWER%"=="quit" goto END
if [%TARGET%] NEQ [] goto SWITCH
echo "%ANSWER%" unknown, please answer Dev or Release. Specify quit to cancel
GOTO ASK
:SWITCH
rem Navigate to the mapping source folder to avoid "Unable to determine the workspace..." error while invoking tf commands.
echo Changing directory context
pushd %SOURCEDIR%
echo Switching to branch %TARGET%
echo - Creating new mapping...
tf workfold /map "%TARGET%" "%SOURCEDIR%"
echo - Get latest version...
tf get "%SOURCEDIR%" /remap /version:T /recursive
popd
goto END
:END
Save it e.g. to switch_branch.cmd and execute from any directory from your machine.
Team Explorer Everywhere has a "Switch to branch" command, which is probably what you're looking for.
Visual Studio, on the other hand, doesn't have the same command...
You can switch between multiple branches, as long as you are using same workspace and the working directory contains the branches.

CVS checkout without all of extra folders

I want to checkout a specific folder from deep within a CVS module into my Hudson / Jenkins workspace. Stripping off the other options (such as pruning, branch, etc) the CVS command is ...
cvs checkout -d workspace module\a\b\c\d\e\f
This causes my folder to contain a child folder 'a' and that contains 'b' and that contains ... well you get the idea. All of them are empty until you get down to folder 'f'.
What I'd really like is for myfolder to contain the contents of f. Does CVS support this functionality (without defining f as a module)?
And for bonus karma ... Can I get Jenkins to use this option with a .cvsrc or some other mechanism?
I don't get the behaviour you describe. When I move to an empty directory and do
cvs checkout -d fox modules/a/quick/brown/fox
I just get a new directory called fox containing the contents of the directory I requested. (Note the forward slashes.)
However, if I do
cvs checkout modules/a/quick/brown/fox
then I get what you describe.
I'm using the latest FSF build of CVS on windows, http://ftp.gnu.org/non-gnu/cvs/binary/feature/x86-woe/cvs-1-12-13a.zip .
There is a file called "modules", under your CVSROOT folder.
You can edit it, and a line like the following:
###shortcut name actual path########
f /a/b/c/d/e/f
Check this file back in. Once it sets in, you can just use
cvs checkout -d workspace f
Also, in Hudson, you can (in the Modules(s) ) box, just put f, and it should directly download only f, instead of the entire structure.
Once that is down, you could rename it using a shell/command.
More in General:
Go up 1 level above where you checked out
cvs co -r "TAG"

Resources