Replace some files using EGit? - eclipse

I use EGit in eclipse.I created a repository for a project and there,I had a class for example ClassA in com.first.pack that was added to index.Then,for some reasons I created another project (that is not under GIT) and copied ClassA in com.second.pack of second project and complete it's task.
Now I'm looking for a way to replace ClassA in com.first.pack with same class in com.second.pack without losing it's history.
I know I can copy content of second class and paste in first one,but really there are some other classes with some situation and it is not a clean way to do for all of them! Also I know there is a replace command in GIT,but I'm not acquaintance with command line and I do not know how I can do it in EGit.
So how I can do that in EGit ?

What do you need it's history ?
You can commit and push your actual situation, then replace com.first.package.ClassA with the ClassA from com.second.package.
GIT will looks like it : you delete the file ClassA, then create a new file called ClasseA
After that commit again and push.
Git will allow you to get history through your dual commit.
In the History View, you will be able to point at a commit ID, then browse through files (created, delete or edited) in the state while performing the commit
At some point, you should be able to get used the commandline, because it allows you to fully use git, and understand what you do.

Related

How to copy a file from one branch to another branch using functionality on Eclipse

Usually, I would just copy the whole content of that file in the current branch and switch to another branch on Eclipse and paste it in the new branch but I am just asking if there is a way I could do this when checking out from Eclipse?
So, I have a branch called Mock branch and it has a file called a.java and I have modified the file. Now, I switch to another branch that also has a.java but different from that of the Mock branch because I have made changes to the a.java in the Mock branch.
Now, how do I push commit on the other branch showing the differences between the a.java in it and that of the Mock branch and applying the changes in Mock branch to the branch I am currently on?
Is this possible in Eclipse?
First of all we will consider that you have pushed the changes of the other branch (so they are HEAD) and you have switched to Mock branch (of course, Im not considering merge between branches because you didn't talk about it ). Starting from this point, let me describe two possible options:
You can do a cherry pick. Cherry pick is a process in which you take a commit from another branch (or even the same) and apply it in your checked out one. As example, if you modify the file of branch A and commit it, you can switch to branch B and do cherry-picking applying this commit from A to B.Of course, keep in mind that cherry pick applies ALL changes added in a commit so if you modify a.java and b.java, both modified files will be applied as a result of the cherry pick. You can get examples from here : https://wiki.eclipse.org/EGit/User_Guide#Cherry_Picking
My favorite and most simple. Do right click in a.java and select Compare with / Branch, tag or reference to get a view that compares the other branch's a.java version with your current Mock branch and use Eclipse editor to apply changes (You can also use Compare with / Commit in case the change you want to apply wasn't at the other branch's HEAD). You can use the arrows to pass changes from right (remote branch) to left (current branch) or even do manually copy- paste
If you want to replace the full content of that file, try and right click on it, and select:
Replace with -> Commit...
Then chose the commit from the other branch.
If you want to replace it with the latest revision from another branch, you can chose
Replace with -> Branch, Tag or Reference
(Here I select master because my current branch is not master, and I want to replace the content of the file with the content of the same file from master.)

Getting job repository URL in Jenkins build plugin

I am writing a build notification plugin for Jenkins. The SCM repository URL (SCM being git to begin with) contains useful information I'd want to get to in my code. Being the beginner with the Jenkins API that I am, I am having trouble figuring out how I should go about retrieving the job's repository location. Is this doable, and if so, how?
The repository is available in the config.xml of the job.
http://[jenkins server]/job/[job]/config.xml
Finally found the answer! The method needed is not defined in the abstract SCM class, but by the classes which extend it. So when you call project.getSCM() you have to then cast it to the type of SCM that you actually have (GitSCM, SubversionSCM, etc.).
I am developing my plugin to work with Subversion, so I looked through the source code for the Subversion Plugin, and found the method getLocations which returns a ModuleLocation[] which contains information on all the SVN repositories in that project. Simply looping through the ModuleLocation[] and calling getSVNURL() gets me the information I want. I can then play around with the SVNURL as needed (toString() gives me the full repository path).
In your case, for Git, the source code shows that there is a method called getRepositories(), which returns a List<RemoteConfig>. Look through the RemoteConfig source code to see which method gets you the information you need. (I believe getURIs() will do the trick).
I managed to get URL of SVN repository for a particular job using following code:
String jobName = manager.build.project.getName()
def job = hudson.model.Hudson.instance.getItem(jobName)
def svnScm = job.scm
def svnLocation = svnScm.getLocations()
def svnURLstr = svnLocation[0].getSVNURL().toString()
Perhaps it will be useful to someone.

Why does mercurial warn me about divergent renames?

I have been using Mercurial version control system for some time already and several times I have seen the system warn me about divergent renames.
What I do is make two different descendants of one larger file. Like for example I've had one class named HttpRequest that was a wrapper for CGI.pm. Later, when I decided to move to the PSGI protocol, I have made two copies of this file, namely Cgi.pm and Psgi.pm. The original class remains and becomes abstract with new ones inheriting from it.
I always thought that it is the preferred way to deal with such situations because each file retains the history of the file that it was based on. But when I push my changes to the remote server, it tells me this:
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 2 changesets with 2 changes to 2 files (+1 heads)
remote: warning: detected divergent renames of lib/HttpRequest.pm to:
remote: lib/HttpRequest/Cgi.pm
remote: lib/HttpRequest/Psgi.pm
Is this bad? Should I do it some other way?
It looks like the problem is not that you made versioned copies of the same source file, but that there are two changesets in which the file was renamed to a different name each time and these changesets are not in the same line of development. This observation is based on the fact that your pull created a new head.
So in this instance, Mercurial is warning you that the pull has created a new head and as a result your repo has two heads inside each of which CGI.pm has been renamed to a different file. Therefore, if you attempt to merge these into one you will have to decide which change should stick.
The simplest way to have prevented this would be to copy the original file instead of renaming it. More precisely, the first time you can rename it but on all subsequent occasions you have to copy it instead (obviously if you do this on the same line of development, and necessary if you do not but intend to merge divergent lines later).
You might also want to look at the relevant section of Mercurial: The Definitive Guide.

Find all unmerged files/elements in ClearCase

We use ClearCase where I work and I'm trying to figure out how to find any files that have been modified but not merged up. We have a main branch at the very top level in ClearCase, and this is where the final source code changes are merged to and where we do our formal release builds from. We then have an integration branch under main where integration issues are worked out. When we get everything working and tested in the integration branch, we merge the integration branch up to main. For individual feature implementations and bug fixes, we create a new branch (usually named after an action, feature, or bugfix) off of the integration branch and work the issue. When we are done with it, we merge that change up to the integration branch.
I was wondering if anybody knew of a command or a way to see what files are modified in the feature/bug fix branches but were not merged back up to the integration branch. I've been looking around but I can't seem to find a way to do it. I would like to be able to run the command and have it tell me all files that have been modified on all of the sub-branches but not merged up. Thanks.
Normally, you use ct findmerge to find files to merge from one branch or view into the current view (assuming ct is an alias for cleartool).
I think you would have to identify all the branches you are interested in and do a separate ct findmerge operation for each branch - for each destination branch. That's complex. You'd also want to be able to eliminate many branches which are known to be fully merged. You can annotate a branch to indicate that it is fully merged.
So, I don't think there is a simple, single command to do this job.
You need to decide which branches are targets that you're concerned about. These would be your integration branch(es). Presumably, you have a fairly small list of these.
For each of those target branches, you need to decide which work branches are relevant to that integration branch. This is the tricky part; there is no easy way to determine whether a particular bug fix or feature branch is relevant to that integration branch using information in the VOBs; it is really only known by the users.
You then need a script that does (in outline):
for int_branch in $(list_relevant_integration_branches)
do
...create view with tag $tag for $int_branch...
ct setcs -f $(cspec_for_integration_branch $int_branch) $tag
ct setview -exec "find_outstanding_merges_for_integration_branch $int_branch" $tag
done
where find_outstanding_merges_for_integration_branch looks a bit like:
vob_list=$(list_relevant_vobs)
for mrg_branch in $(list_relevant_merge_branches $int_branch)
do
echo
echo "Merges from $mrg_branch to $int_branch"
ct findmerge $vob_list -fversion .../$mrg_branch/LATEST -print
done
Note that this command assumes (a) the current view is appropriate for the target, and (b) the integration branch name is passed as an argument.
You can get fancy and decide how to handle automatic or graphical merges instead of -print. The hard part is still the unwritten commands such as list_relevant_integration_branches and list_relevant_vobs. These might be simple:
# list_relevant_integration_branches
cat <<EOF
integration_branch_version_3_0
integration_branch_version_3_1
integration_branch_version_4_0
EOF
# list_relevant_vobs
cat <<EOF
/vobs/mainproject
/vobs/altproject
/vobs/universal
EOF
Or they might be considerably more complex. (If you only have one VOB, then your life is much simpler; the systems we work with have 20-odd VOBs visible in the cspec.)
The other unwritten script is list_relevant_merge_branches. I don't know whether there's a simple way to write that. If you define and apply appropriate attribute types (ct mkattype, ct mkattr) when the development branches are created (perhaps a 'target integration branch' attribute type, an enumeration type), you could use that to guide you. That leaves you with a retrofit problem; how to get the correct attribute onto each existing working branch. You also need a separate attribute to identify branches that no longer need merge scrutiny, unless you decide that the absence of a 'target integration branch' attribute means 'no need to scrutinize any more'. That reduces the retrofit problem to adding the target integration branch to those branches that still need merging; by default, all existing branches will be deemed fully merged.
If you know the source and destination branches (topic detailed in Jonathan's answer, which I have upvoted), then don't forget the query primitive merge:
merge (from-location , to-location)
In all cases, TRUE if the element to which the object belongs has a merge hyperlink (default name: Merge) connecting the from-location and to-location.
You can specify either or both locations with a branch pathname or a version selector.
Specifying a branch produces TRUE if the merge hyperlink involves any version on that branch.
The branch pathname must be complete (for example, /main/rel2_bugfix, not rel2_bugfix).
This thread illustrates that query in action:
How is it possible to find all the elements on a specific branch that are checked in and not merged away?
cleartool find \\view\administration\ProjectVOB \
-branch "brtype(HNH-372452) && \
!merge(...\HNH-372452\LATEST,...\main-372452\LATEST)" -print
\\view\administration\ProjectVOB\Com-API\Dll\COMFrontendDll\Mmi.cpp##\main\HNH-372452
\\view\administration\ProjectVOB\geometry\geochain\geocutterloc.cpp##\main\HNH-372452
That "merge hyperlink" is the red arrow you see in version tree:
(see article "Versioning and parallel development of requirements")

Ensuring a merge between branches happens in one direction

This morning I discovered that my co-worker had merged the wrong way between two branches in mercurial --we have a ver5 and ver6 branch, with extra files in ver6. Is there any way (a serverside hook probably) to enforce that the children of any ver5 node be from ver5?
Whether you have ver5 merged into ver6 or ver6 merged into ver5 you're still ending up with a child of ver5 that has stuff from ver6 in it.
If, however, you want to avoid a changeset whose branch name is ver5 having ancestors that are ver6 you could do that pretty easily with a hook. Just where you put that hook is the tricky part. If you make it a pretxnchangegroup hook you can prevent people from pushing an offending merge into the server-side repo, but they will have already committed it, and maybe some more changes on top of it, and they'll have a hard time figuring out what to do to fix it. If you can control their local setups you can put in a pretxncommit hook that prevents them from committing the merge, but you can't make them run that hook using only Mercurial tools.
The actual hook, whichever type you make it, could use either of these strategies:
check if the branchname is ver5 and if so make sure no specific file/content from ver6 is presnet
or
check if branchname is ver6 and if so make sure neither p1 nor p2 has branchname ver5
TL;DR: It's probably more trouble than it's worth -- stick to shaming.
Rather than post twice, would my answer to "Mercurial: allow merge from a release branch to the default one, but not vice versa" help? https://stackoverflow.com/a/19926324/1025457
This should do it. It uses a revset query to find any merges into ver5 from ver6.
hg log -r 'children(p2(::ver5 and ::ver6 and merge()) and branch(ver6)) and branch(ver5)'
::ver5 and ::ver6 and merge() finds all merges that are ancestors of both ver5 and ver6 branches
p2(...) and branch(ver6) grabs the second parent (incoming changeset) that are on the ver6 branch.
children(...) and branch(ver5) then grabs the actual merge changeset that is on the ver5 branch.
I recently needed to figure this out myself, but also needed to ensure that default wasn't indirectly merged into my release branch, i.e. default -> feature -> release.