I am working on a project that is set up with each group having a server-side clone of our main mercurial repository. The workflow we have been using involves developing on laptops, committing and pushing to the server-side clone repositories and then pulling those changes to a powerful remote machine to run our tests. Once the changes are ready to be shared with the rest of the group, the main server-side clone is pulled and into the local repository and the local repository is rebased against the main clone. The changes can then be pushed to the main remote clone and the history will show a linear history.
The problem is then that the personal server-side clone is totally out of sync with the local repository because it was not rebased. We aren't using proper branches, so merge+rebase and transplant/graft seem to not be what we would use to get the repositories back in sync.
The server-side clone needs to have the same history as the the local repository or it will pull and push ALL of the change sets and be a time consuming mess of resolving non-existent conflicts. How would one get the server-side clone to have the same history as the main and local repositories without stripping and pulling from main? Ideally, we would not have to log into the server.
You can only pull from the 'main' repo to get its history, but this won't delete the not-rebased history from your dev server and local repos.
The only way to have only 'main' history is stripping other repos (or even re-cloning them), and this must be done simultaneously for all repos.
P.s. And don't rebase. It's for private repos only.
Rebasing is deterministic, so you could re-do the rebase in the client clones.
The only cause for concern is if the rebase triggered a merge resolution — in that case you'll have to resolve the merge the same way in the client. Doing that without peeking at the code on the server could be difficult.
Related
I want to clone POX Controller from Github repository into my laptop. The only way I know is by cloning. However, I think if someone clone a project, he/she won't get the updates that the others have done in it. I have read about forking but I don't really understand the difference between fork and clone. So how do I get a project from Github and still be able to receive updates?
Thank you.
To clone a repository means that you will download the whole code of the repository to your laptop.
A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
Most commonly, forks are used to either propose changes to someone else's project or to use someone else's project as a starting point for your own idea. More at Fork A Repo.
as #TimBiegeleisen says, you can get the project and stay updated by clone once then git fetch it periodically.
For example, if you want to cloning POX Controller, clone it:
git clone https://github.com/noxrepo/pox
Then to update it, do the following command on your cloned project:
cd pox // go to your clone project
git fetch
Or you can use git pull instead of git fetch if only need to stay update without keeping your change in the cloned project.
But you must remember the difference between git fetch and git pull. #GregHewgill answers explain it in details:
In the simplest terms, git pull does a git fetch followed by a git merge.
You can do a git fetch at any time to update your remote-tracking branches under refs/remotes/<remote>/. This operation never changes any of your own local branches under refs/heads, and is safe to do without changing your working copy. I have even heard of people running git fetch periodically in a cron job in the background (although I wouldn't recommend doing this).
A git pull is what you would do to bring a local branch up-to-date with its remote version, while also updating your other remote-tracking branches.
Git documentation: git pull
My client is using SVN and my company is using Git (central bare Git repo). So I have the task to sync both servers. I can't use SubGit , because I can't do any modification on either server.
I successfully used git-svn to download the SVN to my local Git repo (using TortoiseGit). But I can't figure out how to set up a remote upstream to the central Git Repository (using Egit in Eclipse).
Is it possible to set up a remote branch, so I can check in the SVN stuff from my local Git into the central Git repo? How?
thanks.
If I understand correctly, you can't update hooks in SVN and Git repositories. That complicates the task a lot, because you can't reject pushes Git if someone is committing to SVN at the same moment and vice versa.
I think, that git-svn is not a solution because on sending commits to SVN ("git svn dcommit") it changes Git commit SHA-1 to add git-svn-id: signature. As result when one pushes commit C to your Git repository, you fetch that commit to your git-svn repsository, run "git svn dcommit", it translates it to SVN and adds git-svn-id: signature to commit message thus changing commit SHA-1, so you'll get another commit C' in git-svn repository. After that C' should be sent back to the Git repository, and after that the user that pushed C should download C' and replace C with C' in his working copy. So you won't have easy and transparent synchronization.
With SubGit you can reduce your problem to synchronization of 2 Git repositories by creation of an "intermediate" Git repository with SubGit installed into it. Synchronization of 2 Git repositories is a simpler task (and there's a lot of solutions on the internet) but it's still isn't a piece of cake, because 2 different users can push into both repositories simultaneously (and you can't discard one of the push, because you can't create hooks in the repositories). If these changes are conflicting, you can resolve that only manually, and I'm afraid this is the best you can do: create a repository with 2 remote and using a script constantly fetch changes from one of them and push the changes to another one and vice versa (and notify the administrator and stop synchronization on simultaneous conflicting changes).
Disclaimer: I can be biased because I'm one of SubGit developers.
I'm using Mercurial with TortoiseHg on a Windwos host.
We have a central repository for the team and it must always be in a stable state.
Now I'm working on a feature with a colleague and we want to merge our work, without going via the central repository because our work isn't stable yet.
So we have a common ancestor, then we have individual commits to our local repos and we need to merge this work and test it, before pushing it to the central repo.
How do we do that?
As a an additonal difficulty, I'm working on Windows with TortoiseHg, while my colleague is on a Linux box. We're both only basic users of Hg, so apologies if this is a question with an evident solution. For me it isn't.
You can use named branches and create special named branch (pushed to central repo) for your WIP
You can use Mercurial in true DVCS-way:
Start embedded web-server on both sides hg serve in the Working Directory
Get URL of repo
Pull from remote side hg pull URL-OF-REMOTE-REPO
I am trying to find out what would be the best way to set up egit repos for mutliple developers.
I found some arguments to set up independant repos for each developer and then the recommendation to merge the files by setting the respective external upstream repo to eg developer B in Eclipse of developer A so A can pull and merge with B. However A then needs to change the repo back to his own all the time. And switching upstream repos in the settings is quite cumbersome.
Alternatively all developers could work off the same repo in different braches - then merging would be easier since noone has to go to settings and change the upstream repo. On the other side this is also kind of "dangerous" since every developer is working on the same repo without restrictions (so I heard)
Which way is better in the long run?
In the long run, having one upstream repository is easier to manage.
Each developer can make their own branches locally.
They should agree on a common branch to push to though. It can be master, or a feature branch (if a few of them are collaborating to a specific feature).
The idea is, before each push, to pull --rebase that branch from the upstream repo in order to replay your local work (the commits you haven't pushed already) on top of upstream/branch (git pull --rebase will fetch and then rebase your local work on top of what has just been fetch).
That way, a developer will only push commits which will be merged on upstream as a fast-forward merge.
In EGit terms, that pull --rebase is configured when you create a tracking branch.
Rebase: When pulling, new changes will be fetched from upstream and the remote tracking branch will be updated. Then the current local branch will be rebased onto the updated remote tracking branch
I'm new to git and am wrapping my head around how I'm supposed to be using git and egit. From the egit tutorial, I have setup a respository on GitHub, pushed my Eclipse projects to the remote GitHub repository from my local workspace, I can push changes to GitHub, switch branches, see the updates on GitHub, etc. This all makes sense.
Looking at the Git Repository explorer, I have a listing of "Local" branches and have no "Remote Tracking" branches and I have no "Remotes" listed. When I create a branch from a local branch, the egit dialog indicates "You are creating a branch based on a local branch" and suggests that I should be making a branch from a remote tracking branch.
So my question is, am I correctly using egit?
Should I just continue pushing changes to the remote GitHub repository? If so, what happens once I share the project and other developers clone the repository and start making changes to the remote repository?
Or should I now ditch the local repository and setup a new remote repository by cloning the existing GitHub repository that I initially created from my workspace?
Or do I create a new Push and Fetch "Remote" for my existing git repository?
Or something else?
Confused.
Since you created the repo on your local system and then pushed it to github without creating a remote you don't have a remote at hand. A remote is simply a short alias for the remote repository's URL. To fix this create a remote and a push and fetch configuration from the repositories view. In order to populate remote tracking branches in your local repo you need to run fetch once. As soon as this is done you can use "Push to upstream" instead of the more complex Team > Push... dialog which allows to define all parameters on the fly. When using native git command line you'll find the same concepts implemented there:
with
"$ git push [url] [refspec]" (e.g. "$ git push https://github/user/myrepo.git master:master")
you pass all parameters explicitly, this is similar to Team > Push... in EGit
with
"$ git push [remote]" (e.g. "$ git push origin")
you push to the repository defined by the configuration parameters of the given remote (check .git/config to see these parameters or open repository configuration from egit preference in Eclipse), this is similar to Team > Push to upstream in EGit. Usually the refspec used in this way is implicitly configured when creating a local branch based on a remote tracking branch. It's also possible to add this configuration later but since this is more
tedious manual configuration the other way is more handy.
If you clone a remote repository the repository you cloned from is stored as remote "origin" in your clone. This way you can skip configuring the remote manually. This is only needed if the repository is born when you create it from scratch.
The "Branching" section of the Egit User Guide can help:
There is no obligation to create a local branch which would be named like a remote tracking branch (see "Having a hard time understanding git-fetch" to have a good understanding of "remote tracing branches).
You can create as many local branches (i.e. branches that you won't necessary push anywhere) as you want/need.
But if you don"t see any remote branch, maybe you didn't fetch that GitHub repo in the first place: see Fetching.