 So let us move on to collaborating with Mercurial, so the first command you will see that is used very often when you are doing collaborative work is what is called clone. So what I will do is I created two directories my project and test, remember my project, this is my project, HG log will tell us our experiments there, we had seven changes that were made, all kinds of changes we made, we moved the file, removed the file, all of the stuff we have done. Now if I want to clone this repository, I can do it very easily, I can say HG clone my project, so I am first thing I did was I cd it out of this directory, notice that I am in slash TMP, not slash TMP slash my project, so now I say HG clone my project to new project. The second directory is optional which means if you do not specify the second directory it will use the same name which you do not want because I do not want the same directory to have my project, debt and my project again, there is no meaning, however if I had done this in my home directory or some other directory then it is fine, am I clear? This new to new project directory is optional, so now if I cd to new project, all I did here was I did HG clone my project to new project, it made the clone, now let us see what has happened, I have a new directory called new project, I will say HG log, it has all of my items, so this is literally a clone of your project, so I now have new project and my project, they are independent clones, unless you explicitly ask to share files technically they are independent, I can make an independent set of changes in one from the other, okay and as I said before all these repositories are self-contained, they have no necessary reference to anything else. Now I will not get into this, sometimes it helps to be able to serve a repository of information so that you are able to share it with somebody else on another machine, at which time what you can do is you can run HG serve, so if on my machine I ran HG serve, if I do HG serve, I need to first be inside a directory cd my project, I do HG serve, now it will basically be running a service on my machine at port 8000, which will show me all of the, this is the project, all of my edits are showing up here, this is my, I can browse the code, I can look at it chain set wise, what is the last chain set? I can look at the graph, so if I want to go say to adding, renaming test as such, it will show me what is the diff, it will show me the files at that level of chain set, is everybody with me? So the, all I did was I ran HG serve serve, and now it has given me a nice webpage where I can see the log, I can see different branches, given a particular log, this chain set I can see the diff, and I can browse the files at that particular version, so I will repeat inside your repository, you simply run the command HG serve, which is given on your slide, and then you visit this location, local host, I will type it here, go to this webpage and you will see this, with which you can browse and look at the, you can also search for example I can say, these are all the things that have referred to the word hello, searching for hello, I can go back, so it is very convenient, and it tells you what is this revision, tells you that this is the tip, you can look at the chain sets, you can look at the files, so I click on this, I can actually see the source code. Now to kill the server, I can hit control C, but the point is once I do serve, I can from some other machine, so let me make another shell, so now if I go to slash temp and I say HG clone, HTTP colon double slash, local host colon 8000, notice that copy in my project also has a pressure of positive, so I have made two clones, I have made new proge and I have made copy of my proge, copy my proge, and notice that when I did this, I use this command HG clone, HTTP or IP address colon 8000, so the nice thing about this is, it allows us to share files extremely easily, and also gives you a nice mechanism by which you can view this information, very fairly conveniently, so now this is a waste, I do not want this copy of my proge, so I can just RM the directory, nothing happens, that copy is gone, if you remove your original directory of course everything is gone, you should at least keep one clone somewhere, so coming back, it is easy to clone in two ways, one is I give it an actual directory, it is clone from the directory, if it is a HG repository, if it is some arbitrary directory there is nothing to clone, the second is you use hd serve or if somebody is serving the HG repository at some place, you can pull or you can clone that repository using that server that they are running, as what I demonstrated to you, so somebody is having a problem with, when I type the command say HG serve it is not open, I am sorry I do not understand, what is not open, HG serve is not open, did you get an error message, so you have to be more specific when you get an error message, I cannot decipher, clearly you saw that it worked for me, I do not do any magic on my machine, you have to make sure if you have a proxy or something that you are not proxying for local host, all of that you have to do, the other thing is, if you want people to share, you may want somebody else to write to your repository, the instant you are doing that it is not that straight forward and I would suggest you actually that may not be a good idea for you to do, because if somebody is going to write to your repository, they can do anything they want, so you have to be a little careful, so I am basically going to skip somebody else writing to your repository, the ideal thing to do is to use some external hosting like Bitbucket or code.google.com, all of them provide free hosting for, free hosting for Mercurial, okay, so the question is local host window is not open by using HG it would not open, HG serve will only start a web server, you have to start Firefox, visit that page, HG serve is not going to open your web browser for you, did you do that, are you saying that the web browser is not working, remember I started Firefox and pointed it to this, it would not by itself just start a repository, a browser, so if I do HG serve nothing will happen, you have to start a browser and point it to that address, okay. So now we have my project and I have new project, how did we make new project, I did HG clone my project new project, correct, this is what I did, that command I ran to get a clone, I demonstrated that if you use serve I can also pull the, I can make a clone from the service that has been provided, so I can say HTTP colon something, IP address and clone from that, so you can clone in many ways, so if you have a project on Google, you can say if you have a web access, you can say HTTP, sorry, HG clone, HTTP colon double slash code.google.com slash blah blah blah, that address you give it will clone from there, okay. So now what you need to do is two things, I now have my new project, okay, so let us make a new commit, I will make some addition, so let me very simple silly shell script, I will just do HG add new.sh, HG check in done, so I have added this one more file and I am now at 8, now I want to share my changes from new project on to my project. Supposing you have set up your HG repository such that you are able to read and write, now obviously if I am on one machine, that guy is on another machine, unless I set the privileges for the other fellow to be able to write, he would not be able to connect. But right now in this case everything is set up because they are both my directories, I can say HG push. When I do HG push, let us go back to my project, notice that it has added my new check in, is this clear? So if you have a clone and you have the clone is such that you have write privileges to the fellow you cloned from and if you do a push, it will push your changes in your current fellow, your clone to the master from whom you cloned. So what did I do? I first cloned, I made a clone and then made a check in new proge, then I pushed from new proge to my proge. So let us look at the help message. So what push does is, it pushes changes from the local repository to the given destination. So I can obviously push to different places if I can specify that particular destination. When you make a clone, by default the destination will be the place where you cloned from, that is a default. So if I want to clone somewhere else, I want to push somewhere else, you have to explicitly specify it. For example, I will make another clone, HG clone my project to some test. Test is now created, so now I go to new proge. So I have new commit saying changing new. I want to push this to test, HG push. So now let us look at my project HG log minus L1, it is still at 8, correct? This is at 9, this is also at 9. So if you specify a destination to push to, it will push to that destination. So the idea is you use push, push your changes to some upstream server, which, where you have right privilege. So if you can push, you must also be able to pull, correct? So what is the problem now? I have my project, let us say my project is on my machine and somebody else's project is on there, your project has your machine, your clone of my project is on your machine. And now I want us to be able to communicate. It is not enough if I push into you and you pull push into me. It is much easier if I push to my, if I committed, updated my repository and you are able to pull from me, right? So one thing that you can do is, you can pull changes from another repository. So let us look at a simple example. I can now say HG incoming from new project. So what it says is new project may, there is another check-in with revision number 9, which is available. So now I can say HG pull, okay? The only thing here is when you do a pull, it has only gotten the code. It has not actually merged, updated your current branch, okay? So to do that, you do HG update. And now this directory also has the change that I have. Notice that it has the new change. Maybe this is too small a font. I will show you another. So I pulled from here all the changes from new project. So what I will do now is, I will repeat this whole process so that you are able to follow. Yeah, I know. I am going a little fast. It is a little complicated. So what I will do is I will take a simple example. I will finish a few more slides. Take the simple example and make another example so that you are able to understand. Just bear with me for a little while. First thing is we clone. I can clone by saying HG clone, some source, optionally specify a destination, okay? Next, given a repository, I can serve a HTTP server from here, from where other people can pull, correct? From where I can also clone. Anybody can clone, okay? And I can also view it using a browser. Given two repositories, one clone of another, if I make changes on say the right hand side on my right and I want to push these changes here, I basically will say HG push on this, specify that clone or that other project and it will push all of these changes into this. The only problem here is I need to have right privileges on this fellow which I may or may not have. On the other hand, I can do the reverse. I can pull, okay? So if I have changes on this side and I want to pull it onto this side, I will say on here, I will say HG pull. So it will pull all the changes from here into this, okay? So remember that once you do a HG pull, you have to do an update. And this is so often, this happens often enough that when you do HG pull, there is an option to HG pull to say HG pull minus U which will automatically do an update. So notice that the update option will update to the new branch head if changes were pulled. So if anything was changed, it will pull the changes and also update your repository. So here is what is happening. I have two repositories. They are both clones. And now this fellow has gone one level up. Somebody has made a check-in. Now I want to get the changes from here to this location, to the one that is lower. I will now do a pull. I will say on this side, I will say HG pull this location. It will grab all the changes from here and make this to this level. Now as soon as this happens, this guy is actually not updated. He has gotten the changes. So when you do update, it will come to actually this level. So essentially it is a two stage process. He has all the changes. This has unchanged. I do a pull. I get all of the version. I do an update and I come back to this, okay? Remember that update simply changes, bumps your current version. And you can go back anytime, anywhere you want. So there are other convenient commands like HG parent which will tell you what are the parents of the working directory. Where is the current working directory? For example, if I did HG update 2, it tells me that I am currently at 2. HG update tells me I am at 9. So parent tells you where you are. Who is your parent? The working directory is parent. So HG update updates the working directory to the tip. Tip is the last working directory. Last change set that is available. That is the latest changes that were made is called tip. And of course, HG tip will also show you what is the tip available. So what I will do is now I will summarize what I have all we have done so far. Number one, HG clone. Source can be either directory or URL. HG serve, HG push, HG pull, HG pull minus U, HG parent. So these are all the new commands that we have done. Have I missed anything? I do not think I have missed anything. Is this clear? So someone is asking me what about change set ID if we push? Nothing. It is the same. And you can do this yourself to find out. Just make two repositories, push, pull and play around with it. You will get a better sense of what to do. So is this clear? Any questions at this point? Because the next topic is going to get a little more inward. So it seems most of you are clear. Let us now, I will give you a simple example again. So let us come and create a fresh repository. HG clone, we already have one, my project to A. Let us use some simple names. A is one user. So this has all of the change set. Let me HG clone A to B. Now I have A and B and they are both clones of each other. So now assume that A is one user, B is another user. So let us say I am A. I make a change. Now A has made a change saying goodbye. Now I am switching to user B. Now user B can say HG pull because B is a clone of A. By default the destination will be A. However A's default destination source will be my project because I clone from my project. So if I do pull without any specification, you have to be careful. So it is safe to say HG pull from A. Just for safety I am going to say A because I specifically wanted to pull only from A. Very often in open source projects this is not an issue because what you will do in that case is you will have the main project. You will clone from there. So then when you push or you pull, you know you are pulling only from there. But here in my contrived example I took my project. My project I cloned into A, then A I cloned into B. So now A is now pointing to my project so it becomes a mess. So what we will do now is I will now pull from B into A. First question is what is the current state of B? It does not have the latest change because only A made the latest change. So let me pull, HG pull. I made a mistake. I said HG pull accidentally dot dot backslash. There is no repository. So it basically says there is an error. Now what happens? I got goodbye. Now I am up to date with B. So this is very nice. Now comes the next problem. Both, so when A makes a change, B did not make a change, B pulls, everything is fine. So if I am only pulling I do not have a problem. Problem comes now is let us do this. We are going to learn some python anyway. So I will write my first python hello world program, finished. So I have written my hello world program and I am very happy. So I say HG add test dot pi HG commit test dot pi. Now this is fine. I made a mistake. I never updated. So now what happens? Now if I do HG update, I have done something very bad. I have now created a branch. So I will have to show you this on the UI if not you will become very confused. What had happened was I pulled from A. What did I do? I first cloned A. Then I pulled from A which means I got the goodbye branch but I did not do an update. What had happened? So I was still stuck in version 9 when I added this test dot pi. But remember nothing has happened. Nothing bad has happened. Now because my new version is the latest I am now stuck. I have version goodbye sitting here and I have my default version which is my current sitting here. So I have a problem. I have what is called two heads. I can either go to 10 and continue from there or I can go to 11 and continue from there. So what do I do? You have to look at one or the other. I can continue to make changes. But now let us go back to A. This fellow is happily at goodbye. There is no confusion. So let us pull the changes from B into A so you have a problem. He is saying I do not know which one you want. There are two heads. That fellow has this. You have this. What you need to do is you need to do what is called a merge. I have two heads. They are branched. I merge these two to make them one. So what I will do now is I will say hg merge. When I do merge what it will do is it will take both of these heads, try to find any conflicting changes. If there are conflicts it will tell you or something is conflicted you have to resolve the conflict. In this case was there any conflict? No. Because the test dot pi is a new file. I modified I think hello. I added goodbye to hello and that fellow added a new file. Now when I do the merge look at the error message it tells me. It says not error message. One file updated, zero files merged, zero files removed, zero files unresolved which is very good. Which means everything went off well and then it says do not forget to commit. So I must know. If I look at status it says there is this test dot pi which is modified hg commit. I will say merging from B's version. Now what it will do is it will merge. Look at look at this changing new was the first version. Then it got to goodbye. Then it jumped. This fellow jumped directly to the python fellow. In between there is this A python fellow. The final fellow is the merge version. So essentially they branched and now by merging them I have brought them back to one line. Now let us go back to B and put that fellow out of his misery. This fellow is still stuck at the point where there is a goodbye and the new python. What should you do now? I can do two things. I can merge directly or A has already done the work. So I will pull from A. The point is remember their repositories and they have all the change information. So when you pull it will realize that A those two versions have been merged upstream and it will sort it out for us. So hg pull and this time I do not want to forget to do an update. So I will do minus u. So it automatically updates. Now hg status. They are good. hg view same status. Does this make sense? So basically even if two fellows have diverged it will give you an opportunity to merge those two, resolve the conflict, put it back and then everybody can continue to work. Now it is obvious that this has lots of uses. So supposing I have Firefox. At one point I will say this is Firefox 1. This is Firefox 2. That will become a branch. It will become another head and I do not have to merge it. That is an independent head which can remain as it is. It is called a branch. Does this make sense? So this is how you handle multiple versions of software. So I will have 7, 7.1, 7.2 will go in this direction. 8 will go here, 8 will go up 8.1 and then there will be the current development unstable version. Typically that is how these software projects work. The idea is very simple. And typically if you have some graphical way by which you can view the log, it is very convenient. For example, let us look at this on the browser. This is the graph. So even if you do not have a fancy tool, you can use the browser to look at the. So if I have, now imagine there is A, B. If there is A, B, C, D, each fellow is diverging somewhere. Same thing will happen. You will have multiple heads and then you merge them and they will all merge into one. So basically everybody is independent. Everybody can go in different directions. If you want to bring them back together, you can merge them. So this process of bringing this line over here to this line over here is called a merge. Now there is one possibility of running into errors again when you are doing multiple mercurial repositories. Now let us say I make a change, B makes a change. So let us try this. I will update just to make sure I do not make any mistakes. So now I do Hg check in minus m. So now B has made this change. Let us see what A can do. What have I done now? So some people are getting little scared because I am doing a lot of things. I am not doing many things. All I am saying is I have two repositories. So I will repeat everything I have said so far. If you have doubts, send me a chat message that you do not understand. I will repeat it. I have two repositories. So I will just draw a little picture to explain what is happening. So I have two users. I have A then I have B. So now at time I am going to use time in increments of some unit. So T equals 1 or T equals 0. They are equal. They are clones. So if I want, so now let us say A goes to T equals 1 or actually I will say revision number is say some, I think it was 9. Was it 9? 9. So it was 9. So I had A, repository A. In repository A I had made 9 changes. I cloned it to B. Revision number is 9. Now they are the same. Whatever changes I make are identical in both sets. Now what do I do? I make a new change. A goes to revision number 10. Now I want to get the changes to B from A. So I do a pull. So I do a HG pull dot dot backslash A and this will also become B's revision number 10. But actually it did not happen. What will happen is this will pull the changes but B's working directory will still be pointing to number 9 because I did not do an update. So actually what happens is it goes, the changes are pulled but working directory here is still pointing to 9 and not to 10. To make this point to this I must do HG update. I did not do it. So what was happening was B is now stuck in version number 9. So what actually happened was I now added a file. So from revision number 9 it went off to version number 11 where I had added test number test dot p y. Do you all remember is this? So I do not know REC is asking me this question. So I am explaining slowly with a picture and all of this. You have to follow it properly. If not you will get lost. So A is very simple. A there is nothing much going on. B is where it became complicated. B has pulled this revision. So now what has happened? If I look at B, B will have two heads. B is going to see on this repository it will see 11 and 10. 11's ancestor is 9 and 10's ancestor is also 9. So essentially it has become like 0, 1, 2, 3 to 9. 9 goes to either 11 or to 10. So what I am doing now is A now decides to pull from B. So A will now get revision number 11. Now A has a problem because he has 10 and he has 11 and these are two different fellows. So now what I did was I took a command called hg merge which took both of these and produced revision number 12 which is merged. So revision number 12 unifies the divergence between 11 and 10 and brings it into one same code base. So what has essentially happened is if I draw the graph I have 1 or 0, 1, dot, dot, dot, 9. 9 became there is a 10 here, 11 here and 11 is merged back to 12 here. Is this clear? This happened on B's fellow and this was made on A's fellow. This process of merging this 10 fellow and 11 fellow is the merge operation to produce one. So basically if you have differing projects like A and B, A was making some changes, B was making independent set of changes, they both differed, they diverged. So if I were to pull from the other fellow there will be a conflict or there will be a merge problem, you will have to merge it. So I will take a simpler example and explain now again. Let us go back. If you look at my shell, hg log minus L1 is now at 13, I have made a modification to Python code and this fellow is updated goodbye. So the chain sets in each is different. Remember that when we merged 12 and this merge, if I merge now pull this merge back to B, they are now identical. A and B again become same. So what I do is, I pull from here and I get, they have 12 and B. So now A and B are identical. Is everybody at least in this room, do you follow? Is it confusing? So I will now, now let us start again from revision number 12. Revision number 12, both are identical, correct? If I look at hg view on one, hg view on the other, both of them will see this graph of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 will be merged. So till 9, 10, 11 and then they are merged together at one. Remember the picture I showed you? Now let us start from scratch at 12. A is at 12, B is at 12, they are both equivalent clones. I make a change to A, I make a change to B, I make different changes, but to different files. So now I say B is very happy, A is also very happy. So I go to A. A does a hg pull minus u from B, correct? I have changed to 13, B has changed. I have to pull that fellow's changes, right? Now notice they have got an error. It says hg merge again. It says there is a problem. It did not say, okay, everything is fine. So we say hg st. What happens is because there were no common changes, there are changes in different files, two heads have now arisen. B has made a change, A has made a change. So let us look at it again. So B has gone to updating python code. A is now updating goodbye and they are different. Notice there is no, they are not in the same common line. What I must do now is merge, hg merge, hg commit. Again I will hg serve and reload. So now if I look at the graph, yeah, the last merge has merged changes from A and B and again brought them back together, okay? So now comes the last example of merging which is merging with conflicts. So far I made, I changed one file. He changed a different file. Then we merge, no problem, right? I changed hello.sh, he changed test.py. So we did not have to do anything. There were no conflicting changes. I was, we were both not saying the same thing. So let us do that. First I will get B to the same level as A. We are still stuck at 13. We need to move to 15. So hg pull minus u. So now let us make a conflicting change. We are both at 15. Now I will make a change to hello.sh and say I am going to remove goodbye word. hgci minus m, hg log minus l1. I am now at 16, okay? Now this fellow says, okay, I will just remove one new line. I will put the new line here and say, okay, I am happy. Okay? Now I will say hgci minus m. I am just putting this in the log so you are able to see what is happening. A is now updated. Hello. Now let me pull changes from B. So hg pull, what is going to happen? Now the problem is I have to update, hg update. It is saying it is cross branches. I have to do a merge. So now I will do hg merge. Now it is giving me a special UI saying these are the three versions. There is the original hello world, goodbye world. Then there is the hello world without the changes. So there are conflicting changes in each. I need to figure out which one to use. So what I need to do is I need to say I want, do I want, no which one is what. Essentially what I will have to do is there are two changes in the same file. So now I will have to figure out which change to get. Make the change, commit that change. I will have to resolve that change, commit it. Essentially I am saying one of us has to decide saying you have changed, I have changed. I will now merge your changes by working over all the conflicts, changing it such that there is one version and then it will continue. So we will do that after TV.