How two people, concurrently editing the same file is handled? - github

I believe the title says it. I'm new to source control thingy.
So, let's say I have two developers working on the same project and they started editing the same file(s) at the same time then everyone of them send the new version at a slightly different time. From what I understand the one who sends the changes last will have his changes kept, the other one's code will be in the archive only!!!
Is that correct?
Please clarify. Thanks.

No, that's not quite correct. It depends somewhat on which version control software you're using, but I like Git so I'll talk about that.
Suppose we have a file Foo.java:
class Foo {
public void printAWittyMessage() {
// TODO: Be witty
}
}
Alice and Bob both modify the file. Alice does this:
class Foo {
public void printAWittyMessage() {
System.out.println("Alice is the coolest");
}
}
and Bob does this:
class Foo {
public void printAWittyMessage() {
System.out.println("Alice is teh suk");
}
}
Alice checks her version in first. When Bob attempts to check his in, Git will warn him that there is a conflict and won't allow the commit to be pushed into the main repository. Bob has to update his local repository and fix the conflict. He'll get something like this:
class Foo {
public void printAWittyMessage() {
<<<<< HEAD:<some git nonsense>
System.out.println("Alice is the coolest");
=====
System.out.println("Alice is teh suk");
>>>>> blahdeblahdeblah:<some more git nonsense>
}
}
The <<<<<, ===== and >>>>> markers show which lines were changed simultaneously. Bob must resolve the conflict in some sensible way, remove the markers, and commit the result.
So what eventually lives in the repository is:
Original version -> Alice's version -> Bob's conflict-fixed version.
To summarise: the first to commit gets in without any problems, the second to commit must resolve the conflict before getting into the repository. You should never end up with someone's changes being clobbered automatically. Obviously Bob can resolve the conflict incorrectly but the beauty of version control is that you can roll back the incorrect fix and repair it.

Much depends on the system you're using.
However in the common case is: who commits his changes second would have to perform a "merge" operation. Meaning s/he would need to compare the two files and come up with a merged version. However (!) many popular system (including IDE) comes with smart tools to assist you doing that.
Here are some tools like that compared:
http://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools

Related

Get file content on Github with GraphQL API and Python

Given a list of repositories on GitHub with 'repoName' and 'userName', I need to find all the '.java' files, and get the content of the java files. Tried to use RestAPI first, but ran into the rate limit very easily, now I'm switching to GraphQL API, but don't know how to achieve that.
Here is how I would do it:
Algo Identify_java_files
Entry: path the folder
Out: java files in the folder
Identify all files in the folder of the repository
For each file
if the type of the file is "blob":
if ".java" is the end of the name of the file
get its content
else if the type of the file is "tree":
Identify_java_files(path of the tree file)
You can easily implement this pseudo code using Python. My pseudo code makes the assumption to use recursion, but it can be done otherwise, it's just for the example. You will need the requests and json libraries.
Here are the queries you might need, and you can use the explorer to test them.
{
repository(name: "checkout", owner: "actions") {
defaultBranchRef {
name
}
}
}
This query allows you to check the name of the default branch of the repository. You will need it for the following queries, or you can use a specific branch but you will have to know its name. I don't know (and don't believe) if you can get all the branches names for a repository.
{
repository(name: "checkout", owner: "actions") {
object(expression: "main:") {
... on Tree {
entries {
path
type
}
}
}
}
}
This query gets the content of the root folder for a specific repository. The expression: "main:" refers to the branch of the repository along with the path. Here the branch is main and the path is empty (it comes after the ":"), meaning we are looking at the root folder. Some repositories are using "master" as default branch, so be sure of which branch to use.
To check the content of a file, you can use this accepted answer.
I updated the example in order for you to be able to try it.
{
repository(name: "checkout", owner: "actions") {
object(expression: "main:.github/workflows/test.yml") {
... on Blob {
text
}
}
}
}
You send your requests to the API using requests or alike, and store the responses as JSON or alike for treatment.
As a side note, I do not think it is possible to achieve this without issuing multiple queries. I recently had to do something similar, and this is my first SO answer, so let me know if anything is unclear.
Edit:
You can use this answer to list all files in a repository.

How does merge work within eclipse?

Perhaps I am looking in the wrong places, but can anyone explain how "Team >> Merge" works within Eclipse? I ended up with instances of git comments interjecting into my code throughout the project, and would like to not have to delete my branch and rebuild.
Example:
<<<<<<< HEAD
static final void method(String input) {
=======
static final void method(String input, int i) {
>>>>>>> master
Your git found a conflict there. You have now both version in your code HEAD and master. You should check which version you want to keep, and remove manually the the rest.
Just literally delete the <<<<<< HEAD stuff, till you only see static final void method(String input) {.
Since I'm working with Android, I didn't use Eclipse in years, but there should be a way to use a GUI for git, so you don't have to delete those lines manually.

TFS 2010 API - Get work items from merge

I need to send an email on completion of a build in TFS 2010 which details the work items associated with check-ins that have been compiled as part of this build. This works no problem via use of the associatedChangesets variable available in the build workflow.
However, in a production situation, we will merge changes from our Development branch into a Release branch. At this point, the build considers there to have only been one change - which is the aforementioned merging of Development into Release. Obviously this is fairly useless as we need to find out which changes where made in the branch that was merged in, and the work items associated.
Does anyone know how to accomplish this using the TFS 2010 API? It seems to be fairly poorly documented from an API perspective. I know you can expand the merge history node in VS2010 but obviously this is no good as this data needs to be collected programatically so a report email can be sent.
OK... I think I found a solution to this although it's clunky and truth be told I'm not exactly sure how it works. But here goes - maybe it will point someone in the right direction.
var associatedWorkItems = new List<WorkItem>();
//Passed in from the build workflow (this variable is available under the 'Run On Agent' sequence as 'associatedChangesets'
IList<Changeset> associatedChangesets = context.GetValue(BuildAssociatedChangesets);
if (associatedChangesets.Count > 0)
{
var projectCollection =
new TfsTeamProjectCollection(new Uri("http://localhost:8080/tfs/DefaultCollection"));
VersionControlServer versionControlServer = projectCollection.GetService<VersionControlServer>();
foreach (var changeset in associatedChangesets)
{
//In order to view the individual changes, load the changeset directly from the VCS.
Changeset localChangeset = versionControlServer.GetChangeset(changeset.ChangesetId);
foreach (Change change in localChangeset.Changes)
{
//Find out what was merged in.
ChangesetMerge[] mergedChangesets = versionControlServer.QueryMerges(
null,
null,
change.Item.ServerItem,
new ChangesetVersionSpec(localChangeset.ChangesetId),
new ChangesetVersionSpec(localChangeset.ChangesetId),
null,
RecursionType.Full);
//Extract work item information from changesets being identified as merged.
foreach (var changesetMerge in mergedChangesets)
{
Changeset actualChange = versionControlServer.GetChangeset(changesetMerge.SourceVersion);
foreach (WorkItem item in actualChange.WorkItems)
{
if (!associatedWorkItems.Exists(w => w.Id == item.Id))
{
associatedWorkItems.Add(item);
}
}
}
}
}
}
Don't ask me exactly how QueryMerges works but all I'm doing here it saying show me what what merged as a part of a changeset checked in. You'll notice that the parameters ChangesetVersionSpec are the same - this means we're just looking at merges from this one changeset.
You'll get back an array of ChangesetMerge objects from QueryMerges(). In the ChangesetMerge class there is a property called SourceVersion - this is the ChangesetId of the original changeset merged in. Once we've got that we can use the VersionControlServer.GetChangeset() method to load the individual set and extract the WorkItem. This is then added to a list of WorkItems which can be manipulated in any way you want (in my case an email). I also used the .Exists() check to make sure the same WorkItem doesn't get recorded twice.
Note that even though you have the collection associatedChangesets from the build workflow, for some reason (for me at least), the Changes[] property inside associatedChangesets was never populated (hence loading each individual changeset using the VersionControlServer.GetChangeset() method as this seems to actually populate all the fields we need.
Like I say, 1. this is a clunky solution (lots of looping - some of which is probably unecessary), 2. I don't fully understand how this works although it seems to produce the required results - I came to this conclusion by doing a lot testing and debugging) and finally - it's the best I could come up with based on the woeful documentation provided by Microsoft.
Hope it helps someone!

Eclipse Plugin Development - Getting information from Team Provider

I am very new to developing eclipse plugins. The biggest hurdle I am facing right now is where/how to get at the data from various other plugins. I am having a real hard time finding documentation for this. For instance the Team Provider plugin....
How do I read the svn revision of a file? Lets say I have an IResourceChangeListener and I want to keep track of the svn revision number of a file (if the user did an update for example).
If I want to ask svn if there are pending updates for a project, how do I talk to the eclipse team provider?
I am not sure where to start...
Thanks!
I eventually discovered what I was looking for after many hours of searching. Unfortunately since I have less than 100 rep. I have been unable to post until now....
I am making a little progress on this. I randomly stumbled upon this while pouring through eclipse source code.
The following code snippet monitors everything that goes on with regard to an svn enabled project. If you save a file, to an update, revert etc. Anything that touches the files or meta data of the files. I just print out the file/direcory name and its revision number.
Subversive version:
final Subscriber subscriber = UpdateSubscriber.instance();
subscriber.addListener(new ISubscriberChangeListener() {
#Override
public void subscriberResourceChanged(ISubscriberChangeEvent[] events) {
for(ISubscriberChangeEvent event : events) {
UpdateSyncInfo info = (UpdateSyncInfo) subscriber.getSyncInfo(event.getResource());
System.out.println(event.getResource().getName()+" revision: "+uInfo.getLocalResource().getRevision());
}
}
});
The real trick was figuring out the entry point to get at this information: UpdateSubscriber. It would be nice if there was a good resource for finding out this sort of information.
Subclipse version:
private static final Subscriber subscriber = SVNWorkspaceSubscriber.getInstance();
private static final ISubscriberChangeListener subsciberListener = new ISubscriberChangeListener() {
#Override
public void subscriberResourceChanged(ISubscriberChangeEvent[] events) {
try {
for (ISubscriberChangeEvent event : events) {
SVNStatusSyncInfo info = (SVNStatusSyncInfo) subscriber.getSyncInfo(event.getResource());
System.out.println(event.getResource().getName() + " revision: " + info.getRepositoryRevision());
}
} catch (TeamException e) {
}
}
};
#Override
public void start(BundleContext context) throws Exception {
super.start(context);
subscriber.addListener(subsciberListener);
}
#Override
public void stop(BundleContext context) throws Exception {
subscriber.removeListener(subsciberListener);
super.stop(context);
}
For general information on the Team API in the Eclipse platform, review the documentation in the help system.
http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/team.htm
(If you're working with the Subscriber stuff, it appears that's mentioned under the "Synchronization Support" -> "Beyond the Basics" topic.)
The Java doc for the team packages also helps:
http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/api/org/eclipse/team/core/package-summary.html
If you're trying to integrate with or otherwise extend the Subclipse or Subversive team providers, you may have better luck asking your question in their forums:
http://subclipse.tigris.org/ds/viewForums.do
http://www.eclipse.org/subversive/newsgroup.php
One starting point would be to explore the sources of subversive to see how they did their implementation of the features you are describing.
The sources for eclipse.team (the common module for all VCS plugins) are available in a Git repo.
The sources for EGit, another VCS plugin (for Git) can also be instructive.

How can I Diff a Svn Repository using SharpSvn

My question is quite simple and with the SharpSvn Api, it should be easy as well. Here what I did:
path = "c:\project";
using (SvnLookClient client = new SvnLookClient())
{
SvnLookOrigin o = new SvnLookOrigin(path);
Collection<SvnChangedEventArgs> changeList;
client.GetChanged(o, out changeList); // <-- Exception
}
and when I call the GetChanged, I get an exception:
Can't open file 'c:\project\format': The system cannot find the file specified.
So, Maybe there is something I'm missing? Or maybe it's not the right way to do find out the list of files and folders that were modified in the local repository?
Thanks in advance.
The SvnLookClient class in SharpSvn is the equivalent to the 'svnlook' console application. It is a low level tool that enables repository hooks to look into specific transactions of a repository using direct file access.
You probably want to use the SvnClient class to look at a WorkingCopy and most likely its Status() or in some cases simpler GetStatus() function to see what changed.
The path that the SvnLookOrigin constructor wants is actually:
path = "c:\project\.svn\";
That is, it wants that special ".svn" directory not just the root of where the source is checked out to.
Although you probably do want to listen to Bert and do something like:
path = "c:\project";
using (SvnLookClient client = new SvnLookClient())
{
SvnLookOrigin o = new SvnLookOrigin(path);
Collection<SvnChangedEventArgs> changeList;
client.GetStatus(o, out changeList); // Should now return the differences between this working copy and the remote status.
}