git-svn on two isolated machines - clone

I have trouble with my development flow..
I have two machines, F and O, both are offline and isolated. F is the main development machine and is connected to and SVN repo. O is also a development machine but without any form of version control. Code developed in F is tested in F then copied in O, tested again and modified, then again copied in F and committed to SVN.
This is done every week. It's tedious, prone to errors, and I lose every edit done on O.
My idea is perform git-svn on F, git clone that repo in a bare repo on usb, and use this bare repo to track changes on O, then pull from this updated bare on F and dcommit con the SVN.
I know it's not good but I have no better idea... Any suggestions?

The full list of recommendations is available here, which does illustrate that working on a cloned Git repository is possible
In your case, it is simpler since you will not svn dcommit from the cloned Git repo in O.
You can import your Git history back to the Git bare repo in F, and dcommit from there, as long as (as commented):
there is no Git merge, and
the history remains linear (new commits added to what was previously git svn fetch).

Related

Administrating a remote non-bare git repo with a GUI

I've also asked this on reddit, but I'm hedging my bets by asking here as well.
We have an employee who needs to be able to treat a remote non-bare repository as if it's a local one. This employee needs to be able to branch, commit, and merge. There are are a few complications.
Employee is on Windows.
Employee has only surface familiarity with git, and needs to be able to do everything via a friendly GUI.
Employee works from home over a spectacularly flakey internet connection.
I believe that a good solution would involve using sshfs to "localize" the remote repo, allowing any git GUI to treat it as if it's local. But we don't know if this will be compatible with an internet connection that comes and goes periodically, and according to the phase of the moon.
Additionally, the senior engineers would prefer finding a GUI client that has built-in support for administrating remote non-bare repos, rather than doing it with an sshfs "hack". Unfortunately, that would rule out SourceTree, with is the preferred choice of the employee in question.
Really, this is two questions in one:
Is there any reason that sshfs would be unsuitable for a use case with infrequent changes, but a shaky connection?
Are there any git GUI clients for Windows that support this functionality built in?
It looks like we have an alternative solution, that sidesteps the problem entirely with git hooks. I'll just paste in the reddit comment:
It's looking like we're going to end up solving this with git hooks, as follows:
Have bare repos at /srv/git, and non-bare repos in the employee's ~ dir
Employee works in local repo, pushes to remote bare repo
Git hook in remote bare repo does the following:
cd ~name/$repo
git fetch --all
git checkout origin/$branch
Thus, the working dir is always the latest commit of the most recently pushed branch.
For the employee, it's as easy as hitting the "Push" button in SourceTree. All the magic happens on the server.

How do I allow 2 people to work on the same local copy of a git repository? Or can I?

This might be verbose, but I'm just starting out with git, so I'm still learning here.
Before now, I've had a team of developers all working off of the same hard drive with a local copy of all of our dev files. So we have 1 hard disk and 4 developers. All of us use sublime text and work on the projects together. We all work in the same room, so it's never been an issue to work on the same project at the same time. We just don't work on the same file at the same time. Not the greatest system, but it worked at the time.
Now we want to introduce git to the team for all of the reasons a VCS is important. The problem we're running into is files being locked by one user and no one else can use git on that repository.
Here's an example. I log into my mac in the morning and make some changes to files in Project X located at /Volumes/dev/projectx/. I open terminal and commit those changes to the local repository (stored also at /Volumes/dev/projectx/). My coworker gets in and logs into his mac. He opens up his terminal to check the status on the repo he's working on. So he moves into /Volumes/dev/projectx/ and runs git status. He gets an error message that says the index is locked. In order to allow him to run any git commands on the repo, I have to completely log out (maybe just kill some processes, but I don't know which ones). After I log out, he can work as though there's no problem.
Is there any way that we can both work on the same local repository at the same time?
I've also discovered that, if I'm working in a project that has a git repository in it and anyone else even opens the project folder in a finder window, it completely locks me out from using that git repo (same index lock error).
We're willing to change the way we work on files, but since there are literally thousands of projects on the drive, it isn't really practical for each of us to have our own local copies of all of the files. Also, since many of the changes are a very simple text change of some kind, it seems tedious to host all of these repositories remotely and have to pull down all the files anytime we only want to update a single file.
I'm really looking for workflow suggestions here, but the question I asked is kind of the starting point here.
The whole point of using git is that you don't have to do this kind of crazy stuff.
I know what you've said about why you don't think you should all have complete copies. Here's the hard truth. You're wrong. Mostly. But that's ok, you said your willing to rethink how you work and that's good. Ill try to explain why its not that big a deal to have everyone use their own clones.
A assume all code is already in a remote repository - if its not, sign up on http://github.com or http://bitbucket.com and get a free repository, add it as a remote to your git repo, and push it up. Its really very simple.
Each of your developers should then make their own directory locally on their machines where they can clone the whole repository.
git clone http://github.com/yuoraccount/yourrepo ~/clones/localproject
The first time they clone, it will take a little time to download everything, but from then on, only each minor diff will need to be downloaded uploaded. Git is made to be efficient that way.
When you make a change, commit it, and push it up.
git commit -am "i made a small change"
git push origin master
Then everyone can pull it down.
git pull origin master
You can even all work on different branches, so your not just pushing to the same branch. This should all be really simple, and very easy to do.
You can also split your project into multiple repositories, but you don't really need to. Thousands of files is not a big deal, git can handle it without a problem. That's not to say that you won't have some challenges. Git is easy to use, but you'll eventually run into merge conflicts. They will be a little bit frustrating at first, but stack overflow has a thousand answers explaining how to deal with them - you should be fine.
This is what git is for.
Git is a decentralized version control system. The way you want to use git could be described as the opposite of decentralized.
There are a number of perfectly reasonable workflows possible with git, but all of them are going to involve each developer working in a local clone of some repo.
i guess that your "single harddisk" is really a single "network storage" that can be accessed concurrently. otherwise i don't see the problem (the harddisk can only be attached to a single computer at any time; whenever you unplug the disk, any locks should be released!)
anyhow, though you currently consider it impractical, you still might consider using per-user clones of the repositories.
the normal workflow of a multi-user repository would consist of a local clone of each repository on each developer machine (that is: a clone on your personal mac).
then the trouble with concurrently accessing the locked central repository doesn't exist!
it's exactly the use-case for which git was designed.
this would allow your users to work on the repository even without having access to your central network storage.
if you are concerned about disk-space, you might be happy to hear that git does a pretty decent job of compressing the data (just run git gc every once in a while in your repository).
if (for whatever reasons) you cannot have local copies (on the dev-machine) of the repositories, you might consider having per-user clones on the central storage.
git can use hardlinks for local clones, so disk-space should not be an issue here.
Section 4 of the Pro Git book (version 2) is about "Git on the Server" and gives some information about what the OP is trying to achieve.
The OP's situation calls for the "Local Protocol".
Here is how this works:
1. Create a local remote from your project
cd into your project and create the remote in your preferred location (in your example /Volumes/dev/projectx):
git remote add origin /Volumes/dev/projectx.git
2. Set the permissions for the remote
git init --bare --shared /Volumes/dev/projectx.git
This will set the permissions properly so that different users can push and pull to/from the remote. This command does not affect your Git history and is safe to run.
The --bare flag is used because all that is needed for a remote is a bare repository, that is, a repository without a working directory (a repository with only the .git directory and nothing else).
Note: this step is not described in the Git Book for the Local Remote protocol and is only suggested when setting up a Git server, but in the experience of a colleague, without using this step, the permissions were not set properly.
3. Push the data to your new remote
Assuming you have a branch called main (do this for any branch you want your collaborators to have access to):
git push --set-upstream origin main
4. Have your collaborators clone the remote
This works as with any remote:
git clone /Volumes/dev/projectx.git
From here on, everybody can push and pull to/from the local remote.

EGit: Cloning bare remote repository, no master?

I'm in the process of convincing my team to move to using git for version control (from svn). The major hurdle seems to be convincing them that it's not going to be too complicated for others. To alleviate that, I'm attempting to create clear documentation. I need some help though with Eclipse/EGit, since I'm not as familiar with them. Coming from a Linux background, I always use git from the command line, but this is a Windows shop and asking IT to install git on everyone's machine will be seen as another layer of complexity.
So far the process for starting a new project is logging into the (linux) development server and creating a bare repository in the appropriate directory. The bare repository is (obviously) empty at this point -- so no master branch yet. This is where the question diverges from the others I've seen on SO, and most of the documentation I can find.
My question is what is the best way to clone that bare, empty repository into Eclipse and set it so that it knows to push to origin/master? I can clone it in the Git Repositories view though it seems unhappy that there's no branch. Then I can switch to the appropriate perspective I'm using for development, create the project, then import the git repo, add files, and finally commit and push and it will finally create the master branch. However this seems convoluted. Is there a more straightforward way to do this?
Thanks for the help!

Maintaining multiple branches of the same base project in VS

I've looked around the site but I couldn't find an answer that covers mine entirely, so please excuse me in advance if I missed it.
I inherited a VB.NET project that didn't have source control (it started as a pet project of a long-gone dev and nobody ever bothered after that to put it in), and by a friend's suggestion I thought about using Git for source control.
The project is a niche product that is customized and sold according to the customer's specs, so that brings the problem that even if 95% of the code is the same for all the customers, sometimes up to 10% of the code is changed and tailored for each customer, by changing or adding lines to existing functions, sometimes adding whole blocks of code, but there's no commonality in the changes between different customers (a function changed in one might not be changed in another).
To complicate things further, due to maintenance contracts, updates made to the baseline app have to be replicated in the customer's branches should they want them, and sometimes changes we make for a specific customer are good enough that we want to put them in the baseline app and replicate them to the other customers, BUT keeping the customizations for each customer!
So with my little knowledge of Git, I thought it would be like:
(customer 1)
C1-----
(main) /
A------B------D
\
\ (customer 2)
C2-----
\
\ (customer 3)
C3-----
...but I can't see how it's going to work after that:
Can I merge SOME changes from the customer's branches into the main trunk WITHOUT merging others that are only useful for that customer?
Can I merge SOME changes from the main trunk into each customer's branches WITHOUT losing the customizations in those branches?
Can I "mark" specific lines of code so they are not merged/committed?
Three or more devs will be working in this, each in his own machine but pushing changes to the company's repository for synchronization. What are the implications for this process?
Right now, every customer has a separate folder and separate project files with all their source code. How would be the import process to put those folders them into Git?
All of this must be done with Visual Studio, with Gitextensions and the Git Source provider for VS. Is it supported, or it has to be done with the console?
Thanks and sorry again if it overlaps with another answer.
I'm relatively new to git and normally use PoshGit for all my operations, so while I may not be able to help you with everything, I hope I can help with some things:
Can I merge SOME changes from the customer's branches into the main trunk WITHOUT merging others that are only useful for that customer?
Can I merge SOME changes from the main trunk into each customer's branches WITHOUT losing the customizations in those branches?
From what I understand, both of these operations can be achieved by using git cherry pick, which allows you to pick a particular commit from one branch, and add it to another without merging the branches together.
For example, assuming you want to add a change made to customer1's repository, to customer2:
First you get the hash ID of the commit from customer 1 that you want to insert into customer2
git checkout customer1Branch
git log
commit 2e8c40025939e8cf41dec70f213da75aa462184b
Author: xxxxxxx
Date: xxxxxx
This made a change that you want...
You then copy the first few characters of the hash you want to cherry pick, change to customer 2's branch and cherry pick it into the branch.
git checkout customer2Branch
git cherry-pick 2e8c40025939e8c
Now, if you do a git log, you'll see your cherry pick at the top. A similar tutorial can be found here (http://nathanhoad.net/how-to-cherry-pick-changes-with-git)
Can I "mark" specific lines of code so they are not merged/committed?
You may find help from a similar question was asked and answered here:
Commit only part of a file in Git
Three or more devs will be working in this, each in his own machine but pushing changes to the company's repository for synchronization. What are the implications for this process?
Since GIT is a fully Distributed VCS, each dev on your team will effectively have a full clone of the central repo on his own machine (complete with full history of that repo.) This means that log history queries and other requests (such as finding out who did what) don't need to go through your central server, but can be done privately and offline by each dev.
Similarly, the changes that each dev makes will become available to all of you (for example, all new branches will be available), but it can sometimes be frustrating to be working on the same features if you're not quite used to git.
As always its a good idea to commit early and often, this will decrease the tension you're likely to face when changes clash. you should also set some structure to when pushes are done, especially if you rely on each other's work to continue.
Another idea you may want to try is having one person in charge of the repo and having him merge changes and patches to help coordinate your efforts.
Right now, every customer has a separate folder and separate project files with all their source code. How would be the import
process to put those folders them into Git?
EDIT
Thanks for clarifying what you meant by this question. You could expand on a similar approach adapted from the answer given here: How do you create a remote Git branch?
Create a new mainline branch for your BASE project and push it to your remote repository.
cd baseProjectDirectory # navigate to your main project directory
git init # git initialize the dir
git add . # recursively add all files in directory to git repo
git remote add <remote-branch-name> <remote-url> # Add the url to your remote directory to your git repo
git commit -m "Initial commit of base project"
git push <remote-branch-name> <local-branch-name>
This will establish your Baseline project on a remote repository called remote-branch-name under a branch called local-branch-name.
You can then navigate to your other projects and repeat these steps putting your repositories under different branches on the same remote, by using new local branch names, i.e. instead of using the local-branch-name when creating a branch, just use a new branch name, such as git checkout -b new-local-branch-name
so if, for example your base project push (the last line of code) was:
git push clientproject base
Where "clientproject" is the name of your remote, and "base" is the name of your local branch, you can just change the line to:
git checkout -b client1 # Creates new branch named client1
git branch -d base # Deletes base branch
git push clientproject client1
Note that while it's not strictly necessary to delete the "base" branch before continuing, it does keep your repository cleaner and is thus considered good practice. Don't worry about losing anything though, your entire git history from base will be copied to client1 on checkout.
Also note: Since your situation requires you to do this from different directories, you'll probably be deleting a branch named "master" and not "base".
Pushing like this will keep client1 on the "clientproject" remote, but will place the project under on a new branch called client1, complete with its own history.
The same steps can be used for the rest of the projects. If I've lost you anywhere along the way, I suggest reading the above link (it's much more concise than I am).
All of this must be done with Visual Studio, with Gitextensions and the Git Source provider for VS. Is it supported, or it has to be done
with the console?
I haven't yet used VS with Git, but I assume most if not all these operations would be supported since they are native git commands.
Hope this helps.

How to commit hg repo with GIT submodule which should be read only?

my Hg repo now needs to include a Git submodule (Restkit) as per the advised method in the site wiki.
However, I am not updating the git contents and should only be potentially reading/pulling in changes from the host.
It appears that when I came to make my first push of my main Hg repo it baulked at the Git one asking for a password. I think this may be because its attempting to authenticate against the Git site as well.
My questions are can I arrange this so that the Git repo is read-only(pull) or even static and/or get round the log in issue. Obviously the two different repos have different credentials.
Thanks.
P.S. using Atlassian SourceTree 1.5.3 on OS X 10.8.2, Xcode 4.5.1
I've just re-read this;
2.6. Synchronizing in subrepositories
Subrepos don't automatically track the latest changeset of their sources. Instead, they are updated to the changeset that corresponds with the changeset checked out in the top-level changeset. This is so developers always get a consistent set of compatible code and libraries when they update.
Thus, updating subrepos is a manual process. Simply run 'hg pull' and 'hg up' in the target subrepo, test in the top-level repo, then commit in the top-level repo to record the new combination. The onsub extension can be used to automate that.
Assume this means its not pulling the sub? but I still have the above issue of the password request.
You moved in the right direction, but not finished all required steps.
You have to have subrepository, create it by hand... and don't mix real subrepository with a) independent b) nested repository
When you'll convert nested to subrepo push into master repo will not perform push to subrepo (except it requested)

Resources