259

For some reason, I only have one repository to use.
But I have multiple projects including java projects, PHP scripts and Android apps projects.

Now my problem is, I have to put them to different sub-folders inside the repository
I use different IDEs, You know, each IDE can have a workspace of itself.

Is there a simple way (say, by design and not by opinion) to solve the problem?

4
  • 1
    A possible solution could be stackoverflow.com/questions/5514739/… or stackoverflow.com/a/7931825/828197 Commented Feb 4, 2013 at 2:32
  • 3
    You're not alone. I have similar case with my repos that I use for learning purposes (example: github.com/hopbit/java-sandbox). I don't want to create new repo to try examples for every new book/tutorial I start to read... Commented Feb 5, 2013 at 10:09
  • 1
    One reason you'd want to do this is if you've got one project that is product code which you deploy to runtime environments like test or production. The second project is an application which system tests (BDD for example) the first project. There is close a relationship between these two projects and now you can maintain/refer to the entirety using one repository url. Commented Apr 12, 2017 at 16:17
  • Summary as below "Git has no idea whether these are parts of the same or different projects" Commented Feb 13, 2019 at 22:51

3 Answers 3

251

While most people will tell you to just use multiple repositories, I feel it's worth mentioning there are other solutions.

Solution 1

A single repository can contain multiple independent branches, called orphan branches. Orphan branches are completely separate from each other; they do not share histories.

git checkout --orphan BRANCHNAME 

This creates a new branch, unrelated to your current branch. Each project should be in its own orphaned branch.

Now for whatever reason, git needs a bit of cleanup after an orphan checkout.

rm .git/index rm -r * 

Make sure everything is committed before deleting

Once the orphan branch is clean, you can use it normally.

Solution 2

Avoid all the hassle of orphan branches. Create two independent repositories, and push them to the same remote. Just use different branch names for each repo.

# repo 1 git push origin master:master-1 # repo 2 git push origin master:master-2 
Sign up to request clarification or add additional context in comments.

13 Comments

Thanks a lot, that should be able to solve my problem. Actually, the two solutions use branchs to hold different projects.
I'm not sure I understand solution 2. Are you saying you commit all the .git files into a master git repo? What's different between using multiple orphaned branches vs using multiple branches?
@Nate What he is saying is this: make two separate local repositories, then push them both to the same remote repository on GitHub.
Thanks @TheGuywithTheElfHat. Now that I look at it again (9 months later) it seems clear to me. Solution 2 is still creating orphaned branches but I can see how this method is easier to deal with.
Solution 2 needs more explanation
|
27

Solution 3

This is for using a single directory for multiple projects. I use this technique for some closely related projects where I often need to pull changes from one project into another. It's similar to the orphaned branches idea but the branches don't need to be orphaned. Simply start all the projects from the same empty directory state.

Start all projects from one committed empty directory

Don't expect wonders from this solution. As I see it, you are always going to have annoyances with untracked files. Git doesn't really have a clue what to do with them and so if there are intermediate files generated by a compiler and ignored by your .gitignore file, it is likely that they will be left hanging some of the time if you try rapidly swapping between - for example - your software project and a PH.D thesis project.

However here is the plan. Start as you ought to start any git projects, by committing the empty repository, and then start all your projects from the same empty directory state. That way you are certain that the two lots of files are fairly independent. Also, give your branches a proper name and don't lazily just use "master". Your projects need to be separate so give them appropriate names.

Git commits (and hence tags and branches) basically store the state of a directory and its subdirectories and Git has no idea whether these are parts of the same or different projects so really there is no problem for git storing different projects in the same repository. The problem is then for you clearing up the untracked files from one project when using another, or separating the projects later.

Create an empty repository

cd some_empty_directory git init touch .gitignore git add .gitignore git commit -m empty git tag EMPTY 

Start your projects from empty.

Work on one project.

git branch software EMPTY git checkout software echo "array board[8,8] of piece" > chess.prog git add chess.prog git commit -m "chess program" 

Start another project

whenever you like.

git branch thesis EMPTY git checkout thesis echo "the meaning of meaning" > philosophy_doctorate.txt git add philosophy_doctorate.txt git commit -m "Ph.D" 

Switch back and forth

Go back and forwards between projects whenever you like. This example goes back to the chess software project.

git checkout software echo "while not end_of_game do make_move()" >> chess.prog git add chess.prog git commit -m "improved chess program" 

Untracked files are annoying

You will however be annoyed by untracked files when swapping between projects/branches.

touch untracked_software_file.prog git checkout thesis ls philosophy_doctorate.txt untracked_software_file.prog 

It's not an insurmountable problem

Sort of by definition, git doesn't really know what to do with untracked files and it's up to you to deal with them. You can stop untracked files from being carried around from one branch to another as follows.

git checkout EMPTY ls untracked_software_file.prog rm -r * (directory is now really empty, apart from the repository stuff!) git checkout thesis ls philosophy_doctorate.txt 

By ensuring that the directory was empty before checking out our new project we made sure there were no hanging untracked files from another project.

A refinement

$ GIT_AUTHOR_DATE='2001-01-01:T01:01:01' GIT_COMMITTER_DATE='2001-01-01T01:01:01' git commit -m empty 

If the same dates are specified whenever committing an empty repository, then independently created empty repository commits can have the same SHA1 code. This allows two repositories to be created independently and then merged together into a single tree with a common root in one repository later.

Example

# Create thesis repository. # Merge existing chess repository branch into it mkdir single_repo_for_thesis_and_chess cd single_repo_for_thesis_and_chess git init touch .gitignore git add .gitignore GIT_AUTHOR_DATE='2001-01-01:T01:01:01' GIT_COMMITTER_DATE='2001-01-01:T01:01:01' git commit -m empty git tag EMPTY echo "the meaning of meaning" > thesis.txt git add thesis.txt git commit -m "Wrote my PH.D" git branch -m master thesis # It's as simple as this ... git remote add chess ../chessrepository/.git git fetch chess chess:chess 

Result

Diagram of merged repositories

Use subdirectories per project?

It may also help if you keep your projects in subdirectories where possible, e.g. instead of having files

chess.prog philosophy_doctorate.txt 

have

chess/chess.prog thesis/philosophy_doctorate.txt 

In this case your untracked software file will be chess/untracked_software_file.prog. When working in the thesis directory you should not be disturbed by untracked chess program files, and you may find occasions when you can work happily without deleting untracked files from other projects.

Also, if you want to remove untracked files from other projects, it will be quicker (and less prone to error) to dump an unwanted directory than to remove unwanted files by selecting each of them.

Branch names can include '/' characters

So you might want to name your branches something like

project1/master project1/featureABC project2/master project2/featureXYZ 

2 Comments

I think the key here is naming branches int folders using "/" character. Then to have separate branches you can do 2 things: 1) Have an actually empty common root commit with git commit --allow-empty -- improvement of solution 3--. 2) Have multiple root commits using git checkout --orphan $project/$branch.
I have 2 folders for 2 different projects, but still untrack changes mixed . i have .git in root folder, and under it I have BE, FE folders, each one contains its own .gitignore file, what should I do to ignore the opposite files ?! thanks a lot
19

I would use git submodules.

have a look here Git repository in a Git repository

As per February2019, I would suggest Monorepos

6 Comments

"I only have one repository to use." Would you care to explain how you would store several submodules in the same repository?
git submodule add [url to git repo] -- git-scm.com/book/en/v2/Git-Tools-Submodules
Could you maybe explain why 'Monorepos' ?
Mentioning Monorepos without telling a bit about why you recommend it is not suitable as an answer, IMHO.
git submodules are okay should you have the individual repositories
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.