Meaning of local or remote in git gui - git-gui

I am somewhat confused what local / remote version means for git gui. At times remotes are my changes and at others local are. Is there any logic behind this naming/handling?

It would depends where, on git-gui you see "local" and "remote".
The only aspect of git where those two terms reference different changes is on a diff view, where local and remote are reversed during a rebase.
See "git rebase, keeping track of 'local' and 'remote'"
A rebase switches ours (current branch before rebase starts) and theirs (the upstream branch on top you want to rebase).
In a GUI mergetool context:
local references the partially rebased commits: "ours" (the upstream branch)
remote refers to the incoming changes: "theirs" - the current branch before the rebase.

Related

How To Pull Latest Files from Dev Branch and NOT master?

I'm new to Git and I'm really confused here. I have a HTTPS from my github, and I am using terminal from a virtual box to try to pull the latest files from one of my branches.
Everytime I use the following command:
git pull http-link or git clone http-link
it only pulls the files from the master branch, and not ALL the branches. I know this because when I run git branch I only see the master branch, and not the develop branch that I have in github. I want the files from this develop branch (NOT master) so I can push the changes to that branch, before merging to master. Please advise.
it only pulls the files from the master branch, and not ALL the branches
The rules for pull are somewhat configuration-dependent, but I can tell you that when you clone it is getting the entire history (all branches) unless you give it specific options telling it not to (such as --single-branch).
I know this because when I run git branch I only see the master branch
That's because by default git branch lists the local branches, and not every known branch from the remote(s). You can say
git branch -a
to see the rest. They'll appear with names like
remotes/origin/branch-name
because what you have are not proper branches; rather these are sort of "bookmarks" that tell you where the remotes branches were, when last you fetched from the remote.
By default, cloning does not automatically create local branches for every branch on the remote (but it does fetch the branches). By default cloning does check out the default branch from the remote (master in this case), creating the local branch for it. And there are shortcuts built in to git such that, in a typical configuration with a single remote, you can say
git checkout branch-name
to create the local branch corresponding to the remote's branch-name branch.
Note that when you do this initial checkout, you don't want to say
git checkout remotes/origin/branch-name
because that does something else. Rather than create the local branch, this simply puts you in "detached HEAD" state, with HEAD on the same commit as the remote branch.

How to use git namespace to hide branches

Background
I'm working with a large team using git for version control. The normal flow is:
People selecting a ticket from the "backlog queue".
Working on the issue via a local branch (i.e. git checkout -b my_feature_branch).
Making several commits as they go (i.e. git commit).
Pushing local changes to a remote branch in order to "backup" their work so it lives on more than one machine, in case the laptop is damaged or stolen (i.e. git push -u origin my_feature_branch).
Eventually creating a code review on our private github page, and doing a squashed merge from the feature branch to master.
In addition to the remote feature branches created by employees on an as-needed basis, we have several dozen release branches that are used to create the "gold builds" we ship to customers, i.e. 1.00, 1.01, 2.00, 2.01, 2.02, etc.
Problem
Some developers have begun to complain that there are too many branches, and I tend to agree. Some developers haven't been diligent about cleaning up old branches when they are no longer needed (even though github provides a one-button delete feature for this once the code review is complete).
Question
Is there a way to configure our company github deployment so that, when people use git branch via the CLI:
Only our "important/release/gold" branches appear.
The one-off developer (temporary) branches only appear via git branch -a?
The main goal of this is to reduce clutter.
Edit: I found a similar question, but the only answer is not at all applicable (don't use remote branches), which violates my key constraint of allowing people to push to remote branches as a form of data backup. The concept of private namespaces, as hinted by #Mort, seems to be exactly what I'm looking for. Now, how do I accomplish that?
Long story short: you can - but it may be a bit tricky.
You should use the namespace concept (give a look here: gitnamespaces)
Quoting from the docs:
Git supports dividing the refs of a single repository into multiple namespaces, each of which has its own branches, tags, and HEAD. Git can expose each namespace as an independent repository to pull from and push to, while sharing the object store
and
Storing multiple repositories as namespaces of a single repository avoids storing duplicate copies of the same objects, such as when storing multiple branches of the same source.
To activate a namespace you can simply:
export GIT_NAMESPACE=foo
or
git --namespace=foo clone/pull/push
When a namespace is active, through git remote show origin you can see only the remote branches created in the current namespace. If you deactivate it (unset GIT_NAMESPACE), you will see again the main remote branches.
A possible workflow in your situation may be:
Create a feature branch and work on it
export GIT_NAMESPACE=foo
git checkout -b feature_branch
# ... do the work ...
git commit -a -m "Fixed my ticket from backlog"
git push origin feature_branch # (will push into the namespace and create the branch there)
Merging upstream
unset GIT_NAMESPACE
git checkout master
git pull (just to have the latest version)
git merge --squash --allow-unrelated-histories feature_branch
git commit -a -m "Merged feature from backlog"
git push # (will push into the main refs)
The tricky part
Namespace provides a complete isolation of branches, but you need to activate and to deactivate namespace each time
Pay attention
Pay attention when pushing. Git will push in the current namespace. If you are working in the feature branch and you forgot to activate the namespace, when pushing, you will create the feature branch in the main refs.
It seems as if the simplest solution here, since you're using GitHub and a pull-request workflow, is that developers should be pushing to their own fork of the repository rather than to a shared repository. This way their remote feature branches aren't visible to anybody else, so any "clutter" they see will be entirely their own responsibility.
If everything lives in a single repository, another option would be to set up a simple web service that receives notifications from github when you close a pull request (responding to the PullRequest event). You could then have the service delete the source branch corresponding to the pull request.
This is substantially less simple than the previous solution, because it involves (a) writing code and (b) running a persistent service that is (c) accessible to github webooks and that (d) has appropriate permissions on the remote repository.
The first answers are good. If you can fork repositories and use pull-requests or just keep the branches for yourself, do it.
I will however put my 2 cents in case you are in my situation : a lot of WIP branches that you have to push to a single repository since you work on multiple workstations, don't have fork possibilities, and don't want to annoy your fellow developers.
Make branches starting with a specific prefix, i.e. wip/myuser/, fetch from / push to a custom refspec, i.e. refs/x-wip/myuser/*.
Here is a standard remote configuration after a clone:
[remote "origin"]
url = file:///c/temp/remote.git
fetch = +refs/heads/*:refs/remotes/origin/*
To push branches starting with wip/myuser/ to refs/x-wip/myuser/, you will add:
push = refs/heads/wip/myuser/*:refs/x-wip/myuser/*
This will however override the default push rule for the normal branches. To restore it, you will add:
push = refs/heads/*:refs/heads/*
Finally, to fetch you WIP branches that are now outside the conventional refs/heads/* refspec, you will add:
fetch = +refs/x-wip/myuser/*:refs/remotes/origin/wip/myuser/*
You will end up with this 2nd remote configuration:
[remote "origin"]
url = file:///c/temp/remote.git
fetch = +refs/x-wip/myuser/*:refs/remotes/origin/wip/myuser/*
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/wip/myuser/*:refs/x-wip/myuser/*
push = refs/heads/*:refs/heads/*
(Git evaluates fetch / push rules from the top to the bottom, and stops as soon as one matches; this means you want to order your rules from the most to the less specific rule.)
People using the standard remote configuration will only fetch branches from refs/heads/*, while you will fetch branches from both refs/heads/* and refs/x-wip/myuser/* with the 2nd configuration.
When your branch is ready to be "public", remove the wip/myuser/ prefix.
The refspec internal documentation was useful to make it.
Please note that once you have push rules in your remote configuration, running the command...
git push
... with no arguments will no longer only push your current branch, nor use any strategy defined with the push.default configuration. It will push everything according to your remote push rules.
You will either need to always specify the remote and the branch you want to push, or use an alias as suggested in this answer.

switching branches with uncommitted changes in git

I am working on my master branch and have some uncommitted changes inside the master branch. I have already created a feature branch and I am able to switch to my feature branch using the git checkout feature_branch command. I have couple of doubts here which I am listing below:
Why am I seeing the uncommitted changes in my branch when I have made my changes inside my master branch. If I commit my changes in the master branch and switch to my feature branch, I do not see the committed changes specific to master. I am expecting the same behavior for uncommitted changes also.
I came across the stash command in Git and there it was mentioned that if you have any uncommitted changes inside the master branch, and would like to switch to some other branch, git will not allow you and hence you need to stash the changes inside the master branch and then only switch to the development branch. I did not face this issue. Am I missing something here and if so, what is the significance of using the stash command?
If I commit my changes in the master branch and switch to my feature branch, I do not see the committed changes specific to master. I am expecting the same behavior for uncommitted changes also.
That's not a sensible behavior. Uncommitted changes are by definition not made to a branch. Branches are pointers to commits, and there is no commit associated with uncommitted changes. They are made to your working directory and have nothing tying them to any branch. They aren't even associated with Git. Until you commit (or stash) them, Git does absolutely nothing to track them, and it will never try to manage them for you.
I came across the stash command in Git and there it was mentioned that if you have any uncommitted changes inside the master branch, and would like to switch to some other branch, git will not allow you and hence you need to stash the changes inside the master branch ...
That's wrong. Stashes don't exist inside any branch. There is one global pool of stashes.
... I did not face this issue.
You will only be prevented from switching branches if doing so would cause your uncommitted changes to be overwritten.
Am I missing something here and if so, what is the significance of using the stash command?
You only need to worry about stashing your changes if they affect any files that would be changed by switching branches. If you have modifications to a file that is identical between two branches, switch from one branch to the other will not require a stash. If the file is different on your other branch, Git will not let you switch branches, as this would destroy your uncomitted changes.
It is safe to try switching branches, and if Git warns you that "uncommitted changes would be overwritten" and refuses to switch branches, you can stash your changes and try again.

git: can I checkout a hotfix branch in a dev environment(with an unmerged dev branch) or will that cross branches?

I'm new to having git set up for multiple users. I typically used it by myself with only one branch. I have a questions that I couldn't find safe answer to via Google:
If I'm currently pulling a feature development branch into my dev server to test the feature and I suddenly discover the need for a hotfix can I re-branch(checkout) the hotfix branch (part of master not dev), pull the files in and start working on/testing a hotfix or will my next "git add ." add the files from the feature branch(which are still on the server) to the hotfix branch therefore mixing the two branches?
If I understand your question, I think your asking if, having changes on the development branch, and then switch to a hot fix branch, will the changes get intermixed with the new branch?
Typically, what I would do is use "git stash save" of any changes on the development branch, checkout the hot fix branch and dothe changes and commit, switch back to the development branch, and then "git stash pop..." To get the development changes back.
You can do "git status" after each step to ensure the working area has what you expect.

git workflow with multiple remotes and order of operations

I have a bare git repository that I use to push to and pull from on a linux machine (let's call the bare git repository remote originlinux). From my working repository that has originlinux as a remote I push and pull until finally I decide to put it on github. I add the repository for github on their web gui and add the remote repository on my working repository (let's call the remote origingithub) using the git remote add command followed by git pull --rebase, then git push (pull before push since I wasn't allowed to simply push to a newly created github repository without getting one of these: 'hint: Updates were rejected because the tip of your current branch is behind'. I figure this has something to do with their option to create a readme file). And here's the issue, after performing these steps, the originlinux repository is completely not synced with the origingithub repository even though they have exactly the same commits and were pushed to from the same exact working repository. Could someone please explain in good detail why this occurring and also what I could do differently to prevent this from happening without reordering how I create my remote repositories? It seems like the workflow or order of operations I'm using doesn't make sense in git land, but how else would you keep multiple remote repositories sync'd on one working copy?
Thanks!
The two repositories do not have the same commits.
When you did git pull --rebase, you rewrote the entire history of the project so that every revision contains that readme file. So every commit in the history will have a different SHA1 identifier.
There are a couple of ways that you may be able to recover from this.
First, you could revert the state of your local repository to match the state or your first (non-github) remote. This would eliminate the readme file that you created on github (you can copy that to some other location and add it back in to git later if desired), along with any changes that you hadn't pushed to the first remote (including changes that haven't been committed).
git reset --hard originlinux/master
git push -f origingithub
The -f option there causes the push to be forced even though that is removing some commits. This is something that should be avoided in general, but it is sometimes necessary such as in this case.
The other option would be to just do a force push to your first remote, accepting the new history caused by the rebase.
git push -f originlinux
If the three repositories that you mentioned are the only ones, it shouldn't matter much which of these methods you use. If there are other repositories you may want try to determine which version of the history is more widely known, and keep that version.

Resources