[System] You are a helpful assistant.

[User]
Multiple bitbucket accounts
I have a Bitbucket account for my 9-5 job and I also have a personal Bitbucket account. My goal is to be able to use both on the same computer. I have installed the latest git on a Windows 7 pc.
So currently everything with my companies Bitbucket account works fine, I can pull/push with no problems. I created a new ssh key using ssh-keygen and assigned a new name in my case "tech". But I am having issues on how to tell a local repo to use the new ssh key I created. I am assuming everytime I try to connect it uses the first ssh key.
I get the error:
$ git push
conq: repository access denied.
fatal: The remote end hung up unexpectedly
I found some advice on the internet but it seems to relate to a linux/git setup, for example I can't find the "config" file on windows.

[Assistant]
This blog post describes a straightforward way to add multiple ssh keys to a single computer and use one ssh key per a bitbucket account. It is much clearer than the official bitbucket documentation. To summarize:
First, make sure you have a default account setup through a tutorial like this one on Github.
For the second account:

Create a new ssh key:
ssh-keygen -f ~/.ssh/<your second account name> -C "<you email>"

Add the ssh key:
ssh-add ~/.ssh/<key file name>

Use pbcopy < ~/.ssh/<your second account name>.pub to copy the public key and add this key to your bitbucket account (in the settings area)

(On Windows you can copy the ssh key using ssh-keygen -f ~/.ssh/<your account name> -c "<your email>" | clip or on Linux you can follow these instructions.)

Add the following to your ~/.ssh/config file. The first sets the default key for bitbucket.org. The second sets your second key to an alias bitbucket-account2 for bitbucket.org:
Host bitbucket.org
  Hostname bitbucket.org
  IdentityFile ~/.ssh/id_rsa

Host bitbucket-account2
  Hostname bitbucket.org
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/<your second account name>

You can now clone projects with your default account the same way as before:
git clone [email protected]:username/project.git

To clone a project with the second identity, replace bitbucket.org with the Host that you specified in the ~/.ssh/config file (i.e. bitbucket-account2 above):
git clone git@bitbucket-account2:username/project.git

That's it!


[System] You are a helpful assistant.

[User]
How to use git-svn to checkout only trunk and not branches and tags?
I'm working on a Java legacy project which has 20 modules connected to each other. So, each module has it's own branch and tag. The structure is like this:

/projects
   .svn
   - module1
       .svn
       -trunk
       -branch
       -tag
   - module2
       .svn
       -trunk
       -branch
       -tag

The projects folder is around 30 GB which is nearly impossible to use git-svn clone to checkout all the modules, but it's because it counts all the branches and tags.
Is it possible to just clone the project only trunk so I can start committing locally?

[Assistant]
Edit: I misread the question and answered what I thought you were asking, not what you actually asked.
To clone just the trunk
Cloning a single Subversion directory is easy, and it actually doesn't matter which directory you clone. Just don't specify any of the "layout" arguments, and give the path to the trunk directly:
git svn clone http://path.to.svn.repo/module1/trunk

To clone a specific module, including tags and branches and so forth
A "normal" git svn clone would look something like the following:
git svn clone --stdlayout http://path.to.svn.repo/

What you want to use instead will be thus:
git svn clone --stdlayout http://path.to.svn.repo/module1/

That will find the trunk, branch and tag subfolders of the module1 folder, and clone them for you.


[System] You are a helpful assistant.

[User] git-switch - Switch branches  --discard-changes

[Assistant]
Proceed even if the index or the working tree differs from HEAD . Both the index and working tree are restored to match
the switching target. If --recurse-submodules is specified,
submodule content is also restored to match the switching
target. This is used to throw away local changes.


[System] You are a helpful assistant.

[User]
Git how to give people push access that needs to be merged in by organizers?
My project has quite a few people and I want to give them all push & pull access because right now, they forked the project and when they make changes, they have to push to their fork and send me a pull request. Instead, I want them to be able to clone the main project at myusername/project and be able to push to it automatically.
So how would I do that?

[Assistant]
Ask for the username of the person you're adding as a collaborator. If they don't have one, they can sign up for GitHub.
In the top right corner of any page, click your username.
On your profile page, click the Repositories tab, then click the name of your repository.
In your repository's right sidebar, click Settings.
Click the "Collaborators" tab.
Start typing the collaborator's username.
Select the user from the drop-down menu.
Click Add.


[System] You are a helpful assistant.

[User]
Github Authentication Failed - ... GitHub does not provide shell access
$ git remote add origin [email protected]:lut/EvolutionApp.git
fatal: remote origin already exists.

$ git push -u origin master
fatal: 'EvolutionApp' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

My keys were added succesfully
 $ ssh -T [email protected]
 Hi lut! You've successfully authenticated, but GitHub does not provide shell access.

The Github article https://help.github.com/articles/generating-ssh-keys/ says that "Shell access" should not be an issue? What could the problem be?

[Assistant]
Try and redefine the ssh url for remote origin:
git remote set-url origin [email protected]:lut/EvolutionApp.git

And try again.
Only git remote set-url can change an existing remote URL (as opposed to git remote add, to add a new remote name and URL)
Here, the issue was the URL of the existing remote 'origin', EvolutionApp: it needed to be replaced by a valid one.
Using git config url."ssh://[email protected]/".insteadOf https://github.com/ would not have helped, considering there was no HTTPS URL in the first place.


[System] You are a helpful assistant.

[User]
Can I use GitHub's 2-Factor Authentication with TortoiseGit?

We like TortoiseGit, and want to take advantage of GitHub's 2-Factor Authentication...but the two don't seem to want to work together.

[Assistant]
To compliment Cupcake's answer, use the Personal Access token feature within GitHub.com while using TortoiseGit:

Set up 2-step auth.
Set up a personal access token - taking note of the generated token (use the Copy to clipboard button next to the generated token).
Set TortoiseGit to remember your password as detailed here.
Now perform a pull operation on GitHub.com, enter your username, but instead of using your normal password, use the token that was generated in step #2.
Perform another pull operation on GitHub.com to ensure the token is remembered.


[System] You are a helpful assistant.

[User] git-rev-list - Lists commit objects in reverse chronological order  --left-right

[Assistant]
Mark which side of a symmetric difference a commit is reachable from.
Commits from the left side are prefixed with < and those from
the right with > .  If combined with --boundary , those
commits are prefixed with - . For example, if you have this topology: y---b---b  branch B
	    / \ /
	   /   .
	  /   / \
	 o---x---a---a  branch A you would get an output like this: $ git rev-list --left-right --boundary --pretty=oneline A...B

	>bbbbbbb... 3rd on b
	>bbbbbbb... 2nd on b
	<aaaaaaa... 3rd on a
	<aaaaaaa... 2nd on a
	-yyyyyyy... 1st on b
	-xxxxxxx... 1st on a


[System] You are a helpful assistant.

[User]
fatal: unable to access ".....": gnutls_handshake() failed: Handshake failed

I've been using Git for the past few months. Recently when I try to clone or to push, I keep on getting this error. I've researched on the internet but so far no solution has worked for me. Does anyone have an idea?
External note : Now I moved to different country, it was working perfectly where I was before.
Git Version : 2.11.0   , OS : Debian GNU/Linux 9.11 (stretch)
Error :
git push
fatal: unable to access 'https://**************/': gnutls_handshake() failed: Handshake failed

[Assistant]
This is solution fix this issue on ubuntu server 14.04.x
1, Edit file:
sudo nano  /etc/apt/sources.list

2, Add to file sources.list
deb http://security.ubuntu.com/ubuntu xenial-security main
deb http://cz.archive.ubuntu.com/ubuntu xenial main universe

3, Run command update and update CURL to new version
apt-get update && apt-get install curl

4, Check version (Optional):
curl -V
Response :

curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.28 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets

5, Test connect with bitbucket (Optional)
GIT_CURL_VERBOSE=1 git ls-remote https://bitbucket.org/
Response:

* Closing connection 0
fatal: repository 'https://bitbucket.org/' not found

This done.


[System] You are a helpful assistant.

[User]
What's the use of the staging area in Git?
What is the point of git add . or git add <filename> to add it to the staging area? Why not just  git commit -m "blabla"?
I don't understand the value of the staging area.

[Assistant]
There are many uses of staging in Git. Some are listed below:

staging helps you split up one large change into multiple commits - Let's say you worked on a large-ish change, involving a lot of files and quite a few different subtasks. You didn't actually commit any of these -- you were "in the zone", as they say, and you didn't want to think about splitting up the commits the right way just then. (And you're smart enough not to make the whole thing one honking big commit!).
Now the change is all tested and working, you need to commit all this properly, in several clean commits each focused on one aspect of the code changes.
With the index, just stage each set of changes and commit until no more changes are pending. Really works well with git gui if you're into that too, or you can use git add -p or, with newer gits, git add -e.

staging helps in reviewing changes - Staging helps you "check off" individual changes as you review a complex commit, and to concentrate on the stuff that has not yet passed your review. Let me explain. Before you commit, you'll probably review the whole change by using git diff. If you stage each change as you review it, you'll find that you can concentrate better on the changes that are not yet staged. git gui is great here. It's two left panes show unstaged and staged changes respectively, and you can move files between those two panes (stage/unstage) just by clicking on the icon to the left of the filename. Even better, you can even stage partial changes to a file. In the right pane of git gui, right click on a change that you approve of and choose "stage hunk". Just that change (not the entire file) is now staged; in fact, if there are other, unstaged, changes in that same file, you'll find that the file now appears on both top and bottom left panes!

staging helps when a merge has conflicts - When a merge happens, changes that merge cleanly are updated both in the staging area as well as in your work tree. Only changes that did not merge cleanly (i.e., caused a conflict) will show up when you do a git diff, or in the top left pane of git gui. Again, this lets you concentrate on the stuff that needs your attention -- the merge conflicts.

staging helps you keep extra local files hanging around - Usually, files that should not be committed go into .gitignore or the local variant, .git/info/exclude. However, sometimes you want a local change to a file that cannot be excluded (which is not good practice but can happen sometimes). For example, perhaps you upgraded your build environment and it now requires an extra flag or option for compatibility, but if you commit the change to the Makefile, the other developers will have a problem. Of course you have to discuss with your team and work out a more permanent solution, but right now, you need that change in your working tree to do any work at all! Another situation could be that you want a new local file that is temporary, and you don't want to bother with the ignore mechanism. This may be some test data, a log file or trace file, or a temporary shell script to automate some test... whatever. In git, all you have to do is never to stage that file or that change. That's it.

staging helps you sneak in small changes - Let's say you're in the middle of a somewhat large-ish change and you are told about a very important bug that needs to be fixed asap. The usual recommendation is to do this on a separate branch, but let's say this fix is really just a line or two, and can be tested just as easily without affecting your current work. With git, you can quickly make and commit only that change, without committing all the other stuff you're still working on. Again, if you use git gui, whatever's on the bottom left pane gets committed, so just make sure only that change gets there and commit, then push!


[System] You are a helpful assistant.

[User] git-config - Get and set repository or global options  core.unsetenvvars

[Assistant]
Windows-only: comma-separated list of environment variables'
names that need to be unset before spawning any other process.
Defaults to PERL5LIB to account for the fact that Git for
Windows insists on using its own Perl interpreter.


[System] You are a helpful assistant.

[User]
How can I tell which remote "parent" branch my branch is based on?
I have a scenario in which there a several remote tracking branches within my local repository that I must sync up to. Our workflow model is:

make a branch locally, based off of the desired remote tracking branch
make our changes
build/test/fix
commit
push back to the remote server

I've noticed that "git status" doesn't show me what branch my local branch is based on unless something has changed; i.e. uncommitted local changes or a recent fetch puts my local branch behind the times.  Is there some way of knowing what branch my local branch is based on without having to change things?  Something like, "git status -showparentbranch" or some other command that would show this.  Occasionally I run into this need but don't know yet how to satisfy it.

[Assistant]
try this:
git log --graph --decorate


[System] You are a helpful assistant.

[User] git-diff - Show changes between commits, commit and working tree, etc  --no-color

[Assistant]
Turn off colored diff.
This can be used to override configuration settings.
It is the same as --color=never .


[System] You are a helpful assistant.

[User]
How to assign a Git SHA1's to a file without Git?
As I understand it when Git assigns a SHA1 hash to a file this SHA1 is unique to the file based on its contents.
As a result if a file moves from one repository to another the SHA1 for the file remains the same as its contents have not changed.
How does Git calculate the SHA1 digest? Does it do it on the full uncompressed file contents?
I would like to emulate assigning SHA1's outside of Git.

[Assistant]
This is how Git calculates the SHA1 for a file (or, in Git terms, a "blob"):
sha1("blob " + filesize + "\0" + data)

So you can easily compute it yourself without having Git installed. Note that "\0" is the NULL-byte, not a two-character string.
For example, the hash of an empty file:
sha1("blob 0\0") = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"

$ touch empty
$ git hash-object empty
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

Another example:
sha1("blob 7\0foobar\n") = "323fae03f4606ea9991df8befbb2fca795e648fa"

$ echo "foobar" > foo.txt
$ git hash-object foo.txt
323fae03f4606ea9991df8befbb2fca795e648fa

Here is a Python implementation:
from hashlib import sha1
def githash(data):
    s = sha1()
    s.update("blob %u\0" % len(data))
    s.update(data)
    return s.hexdigest()


[System] You are a helpful assistant.

[User]
Git pre-commit hooks only for a specific subfolder?
I currently have a single repo with two projects, each in their own subfolder: one in C# and one in Javascript. I want to have a pre-commit hook that will run jshint but only if any of the staged files are in the Javascript folder If the staged files are only from the C# folder, then the pre-commit hook won't run.
Is it that possible at all? Or is my only solution to split the two projects into their own repos?

[Assistant]
If you use pre-commit, specify files to include (or exclude to exclude) specific directories, e.g. run hooks only in my_dir:
files: ^my_dir/
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    hooks:
        ...

or run everywhere but inside my_dir:
exclude: ^my_dir/
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    hooks:
        ...

If you have a long list of exclusions, use verbose regex:
exclude: >
  (?x)^(
      path/to/file1.py|
      path/to/file2.py|
      path/to/file3.py
  )$

you can also apply these to specific hooks only, just do:
-   id: my-hook
    exclude: ^my_dir/


[System] You are a helpful assistant.

[User]
Unable to auto-detect email address
I'm new to SmartGit. I can't commit through my repository, the message I'm receiving is:
Unable to auto-detect email address (got 'Arreane@Arreane-PC.(none)')

*** Please tell me who you are.

Run
  git config --global user.email "[email protected]"
  git config --global user.name "Your Name"

to set your account's default identity.

Omit --global to set the identity only in this repository

I'm using a different PC, but if I commit at home it commits and pushes perfectly, I don't know if this was the cause of the problem.
I've searched around and others say to edit the .git/config file, but I cannot find this file.
What am I missing?

[Assistant]
Well, the message is pretty much self-explanatory. You did not tell git what your name and email address is.
Open a command line and type:
git config --global user.email "[email protected]"
git config --global user.name "Your Name"

Of course you should enter your real name and email.
Afterwards git knows who you are and is able to insert this information in your commits.
Seems like smartgit does not add the git binary to your path. You have to add its path to the PATH environment variable or first change to the corresponding directory. You can find a screencast here: http://blog.dragndream.com/?p=97


[System] You are a helpful assistant.

[User]
How to default to side-by-side view in GitLab

How can I make Side-by-side be the default diff for my GitLab installation or project or profile?

[Assistant]
Update February 2016
The issue is now at issue CE 3071 and... was resolved by commit 9fdd605!
A cookie now retain your diff view choice, with GitLab 8.5.0+.

Original answer (February 2015)
That doesn't seem to be possible right now, and can be voted up at the  suggestion 7082397

Remember side-by-side diff choice
Right now when I want to review code, I have to choose side-by-side diff each time I open a Merge Request because that choice is not stored/saved anywhere.
Either store my last choice/change of viewer globally somewhere and use it on all diff views from that point on.
Or let me have a config option on my account where I can specify my preferred choice.

The side-by-side diff view was introduced with GitLab 6.4 (Dec. 2013) with commit b51c2c8.


[System] You are a helpful assistant.

[User]
Do I need to publish to npm every time I update a package available via git?
Say I maintain an incredible crab-season package.  I've npm published version 0.1.0 with a package.json containing:
"repository": {
  "type": "git",
  "url": "https://github.com/example/crab-season.git"
}

When I add awesome new features, bump the version to 0.2.0, and push to github will the npmjs registry notice my new version or do I need to npm publish each time?

[Assistant]
Travis CI can publish to npm when you push a version tag to reduce the overhead of releasing a change.  Enable in your .travis.yml with:
deploy:
  provider: npm
  api_key: "YOUR API KEY"
  on:
    - tags: true

Check the travis docs for details.  There's also a step-by-step guide in this post.


[System] You are a helpful assistant.

[User]
Git Cherry-Pick and Conflicts
There are two different git branches. In one the development is going in (Branch1).
In other branch some PoC work is going on (Branch2). Now, I want to cherry-pick the changes from Branch1 to Branch2, so that Branch2 is up to date.
Now, after cherry-picking 4 or 5 changes, I am getting some merge conflict and I am unable to proceed with further cherry-picks.
Do, I need to resolve all the conflicts before proceeding to next cherry -pick or Can I somehow postpone the conflict resolution till I cherry-pick all the changes (and resolve all conflicts together)?
Further, is it suggested to do cherry-pick or branch merge in this case?

[Assistant]
Before proceeding:

Install a proper mergetool. On Linux, I strongly suggest you to use meld:
sudo apt-get install meld

Configure your mergetool:
git config --global merge.tool meld

Then, iterate in the following way:
git cherry-pick ....
git mergetool
git cherry-pick --continue


[System] You are a helpful assistant.

[User] git-log - Show commit logs  %b

[Assistant] body


[System] You are a helpful assistant.

[User]
Git/GitHub commit with extended message/description

I recently use GitHub and downloaded GitHub for Mac.
I noticed you can add an 'extended description' using GitHub for Mac. How do I add an extended description using the command line?
Can I add an extended description to an existing commit?

[Assistant]
From this accepted answer:
git commit -m "Title" -m "Description .........."


[System] You are a helpful assistant.

[User]
git ignore vim temporary files
What is the correct way to make git ignore temporary files produced by vim in all directories (either globally across the system or locally for a single project)?

[Assistant]
Vim temporary files end with ~ so you can add to the file .gitignore the line
*~

Vim also creates swap files that have the swp and swo extensions. to remove those use the lines:
*.swp
*.swo

This will ignore all the vim temporary files in a single project
If you want to do it globally, you can create a .gitignore file in your home (you can give it other name or location), and use the following command:
git config --global core.excludesfile ~/.gitignore

Then you just need to add the files you want to ignore to that file.
If you want to comment in a Git file you must do this on a separate line:
# Ignore vim files:
*~
*.swp
*.swo

Any comments placed on the same line as an active git ignore will cause the whole line to be misinterpreted.


[System] You are a helpful assistant.

[User]
Describe your workflow of using version control (VCS or DVCS) [closed]
Closed. This question needs to be more focused. It is not currently accepting answers.

Want to improve this question? Update the question so it focuses on one problem only by editing this post.

Closed 10 years ago.

                        Improve this question

I'd like to learn other people workflow when using either vcs or dvcs.
Please describe your strategy to handle the following tasks:

Implement a feature
Fixing bugs (during development and deployed app)
Code Review
Refactoring code (post code-review)
Incorporate patches
Releasing the newer version of your app (desktop, web, mobile, would you treat them differently?)

Feel free to organize your answer not grouped by the tasks but grouped by whatever you think is relevant but please organize it by VCS/DVCS (please don't mix them).
Thank you.

[Assistant]
The main feature all VCS use for the various task you are mentioning is branching: the ability to isolate a development effort in a collaborative way. Since it is a Central VCS, several developers can collaborate on a same branch, with pessimistic or optimistic locks on files, in order to develop a parallel history.
But being a VCS has two major impact on branching:

It tends to discourage commits, because once a file is committed, it will immediately influence the workspace of other views with the same configuration (i.e. "working on the same branch").
~ The "publication" process is an active one, with immediate consequences,
~ while the "consuming" part (updating your workspace) is a passive one (you are forced to deal with changes published by other immediately upon update of your workspace)
It works well for linear merge workflow (i.e. "only merge from branch A to branch B, not mixing merges in both directions" -- A to B to A to B...). The merges are trivial, all modifications from A are simply carried over to B

Now:
Implementing a feature
Any VCS will do that by making a branch, but what greatly surprised me is that a "feature" branch is not easy:
* the feature may grow too complicated
* it may be ready in time for the next release
* only some part of it may need to be merged back into the main development branch
* it may depend on other features which are not fully done yet
So you need to be careful in the way you manage your feature branch, and your commits: if they are tightly related to the same feature, it will go well (you merge the whole thing back to your main development branch when you need it). Otherwise, partial merges are not easy with those tools.
Fixing bugs
The difference between bug fix during development and after release is that, in the former case you can often do it linearly in the same branch, as in the latter case you will have to establish a bug-fix branch, and decide what bugs you will need to back-port to your current development branch.
Code Review
It is best used with external tools (like Crucible for instance), and uses VCS functions like blame or annotations extensively, in order to better assign code fixes after a review.
Refactoring code (post code-review)
If the refactoring is minor, it can go on in the same branch. But if it is big, a special branch needs to be setup, with unit-testing done before beginning said refactoring.
Incorporate patches
Same comment as last point. If the patch is a big one, a branch needs to be created.
Releasing the newer version of your app
A VCS will only get you so far when it comes to releasing your app, because it is not a release management tool.
You will need to formerly identify a version to be released (label), but after that comes the deployment process which involves:

stopping what is currently running
copying the new files
deploying them (updating sql database, webapp, ...)
instantiating all config files (with the right values, addresses, port number, paths, ...)
restarting (and if your system is composed of several components, restarting them in the right order!)

The key things with VCS and release management are:

they are not very well adapted to store binaries to be released, meaning you need them to build your app, not to store the resulting executable
they are not always welcome in the production environment (where security constraints limit writing access, as well as the number of tools running on those platforms, essentially monitoring and reporting tools)

The release mechanism also has an influence on binary dependencies:

for external binary dependencies, you will probably use mechanisms like maven to get fixed revisions of external libraries
but for internal dependencies, when you are not developing just one app but several which depends one upon an other, you need to know how to reference the binaries produced by the other apps (internal binary dependencies), and they usually won't be stored in your VCS (especially in the development phase, where you can produce a lot of different releases for your other apps to be able to use)

You can also choose to be in source dependencies (and get all the sources of the other internal projects you need for your own), and a VCS is well adapted for that, but it is not always possible/practical to recompile everything.


[System] You are a helpful assistant.

[User]
How to avoid having to do "git branch --set-upstream", and instead default to automatically setup remote tracking?
I create a new branch in Git:
git branch my_branch

Push it:
git push origin my_branch

Now say someone made some changes on the server and I want to pull from origin/my_branch. I do:
git pull

But I get:
You asked me to pull without telling me which branch you
want to merge with, and 'branch.my_branch.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "my_branch"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

I learned that I can make it work with:
git branch --set-upstream my_branch origin/my_branch

But why do I need to do this for every branch I create? Isn't it obvious that if I push my_branch into origin/my_branch, then I would want to pull origin/my_branch into my_branch? How can I make this the default behavior?

[Assistant]
Git v2.37.1 and above
If you are using the mentioned version or above you can use this new config entry to automatically setup remote tracking:
git config --global push.autoSetupRemote true
After that, when you do git push tracking is setup automatically. No need for git push -u origin my_branch

A shortcut, which doesn't depend on remembering the syntax for git branch --set-upstream 1 is to do:
git push -u origin my_branch

... the first time that you push that branch. Or, to push to the current branch from a branch of the same name (handy for an alias):
git push -u origin HEAD

You only need to use -u once, and that sets up the association between your branch and the one at origin in the same way as git branch --set-upstream does.
Personally, I think it's a good thing to have to set up that association between your branch and one on the remote explicitly.  It's just a shame that the rules are different for git push and git pull.

1 It may sound silly, but I very frequently forget to specify the current branch, assuming that's the default - it's not, and the results are most confusing.
Update 2012-10-11: Apparently I'm not the only person who found it easy to get wrong! Thanks to VonC for pointing out that git 1.8.0 introduces the more obvious git branch --set-upstream-to, which can be used as follows, if you're on the branch my_branch:
git branch --set-upstream-to origin/my_branch

... or with the short option:
git branch -u origin/my_branch

This change, and its reasoning, is described in the release notes for git 1.8.0, release candidate 1:

It was tempting to say git branch --set-upstream origin/master, but that tells Git to arrange the local branch origin/master to integrate with the currently checked out branch, which is highly unlikely to be what the user meant. The option is deprecated; use the new --set-upstream-to (with a short-and-sweet -u) option instead.


[System] You are a helpful assistant.

[User]
How do you fix a bad merge, and replay your good commits onto a fixed merge?
I accidentally committed an unwanted file (filename.orig while resolving a merge) to my repository several commits ago, without me noticing it until now. I want to completely delete the file from the repository history.
Is it possible to rewrite the change history such that filename.orig was never added to the repository in the first place?

[Assistant]
Please don't use this recipe if your situation is not the one described in the question. This recipe is for fixing a bad merge, and replaying your good commits onto a fixed merge.
Although filter-branch will do what you want, it is quite a complex command and I would probably choose to do this with git rebase. It's probably a personal preference. filter-branch can do it in a single, slightly more complex command, whereas the rebase solution is performing the equivalent logical operations one step at a time.
Try the following recipe:
# create and check out a temporary branch at the location of the bad merge
git checkout -b tmpfix <sha1-of-merge>

# remove the incorrectly added file
git rm somefile.orig

# commit the amended merge
git commit --amend

# go back to the master branch
git checkout master

# replant the master branch onto the corrected merge
git rebase tmpfix

# delete the temporary branch
git branch -d tmpfix

(Note that you don't actually need a temporary branch, you can do this with a 'detached HEAD', but you need to take a note of the commit id generated by the git commit --amend step to supply to the git rebase command rather than using the temporary branch name.)


[System] You are a helpful assistant.

[User]
On GitLab, how to compare a file of two different commits

On GitLab, how to compare a file of two different commits? I know that that on command line git, the command is:
git diff commit1 commit12 -- file_name

What is the link format to do this on GitLab?
See my related question

[Assistant]
It will compare commits, you will be able to find file in list.

go to Repository > Compare
paste this url: https://gitlab.com/$USER/$REPO/compare?from=$SHA1&to=$SHA2 or https://your gitlab domain/$ORG/$GROUP/$REPO/-/compare?from=$SHA1&to=$SHA2
hit enter (notice: gitlab will set 'Source' and 'Target' properly)
click button 'compare'


[System] You are a helpful assistant.

[User]
git command could not be found and could not find ssh-agent
I was on GitHub today and realized I was behind on updates from a repo. I tried to fetch updates, but it failed from the outset. I received two messages when I started up Git Shell (from GitHub for Windows):

Warning: git command could not be found. Please create an alias or add it to your PATH.
Warning: Could not find ssh-agent.

When I attempted to enter "$ git fetch origin", I got the following error message:

The term '$' is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.

I also tried omitting the $ sign, but that didn't change anything.
I have no clue what's going on, the last time I used the Shell (beginning of this month), it did not do this. I have tried adding the path to git.exe to the PATH environment variable, but that did not work - nothing appeared to change. I have not restarted my computer after doing so, is that the problem? I have also never set up Git to use SSH.

[Assistant]
It sounds like you recently updated GitHub application and Git Shell is now broken.
Short version
To fix it

close Git Shell
open GitHub and let it do some post installation.
Open Git Shell again and you should be fixed.

Long version
This just happened to me and just to make sure I follow you, you just did this

Open Git Shell
You are prompted to update GitHub
After the update, Git Shell opens

Now it gives the error

git command could not be found. Please create an alias or add it to
  your PATH.
Warning: Could not find ssh-agent.

If this is the case, do this

Close Git Shell
Now open the GitHub application (not Git Shell).

This will say something along the lines of (not sure of the exact version)

GitHub is extracting git..

Let that go through the process and after it is complete, go open Git Shell and it is fixed. Just worked for me at least.


[System] You are a helpful assistant.

[User]
How to specify a git commit message template for a repository in a file at a relative path to the repository?
Is there a way to specify a git commit.template that is relative to a repository?
For configuration an example is
$ git config commit.template $HOME/.gitmessage.txt

But I would like to specify a template file relative to the .git folder of the repository.

[Assistant]
This blog tipped me off that if the path to the template file is not absolute, then the path is considered to be relative to the repository root.
git config commit.template /absolute/path/to/file

or

git config commit.template relative-path-from-repository-root


[System] You are a helpful assistant.

[User] git-push - Update remote refs along with associated objects  git push origin :experimental

[Assistant]
Find a ref that matches experimental in the origin repository
(e.g. refs/heads/experimental ), and delete it.


[System] You are a helpful assistant.

[User]
How to rebase a branch off a rebased branch?
So my history looks like this:

o---o---o---o  master
     \
      o---o---o  A
               \
                o B

So, to explain:

I have branch A which was started from master
I have branch B (with only 1 commit) which was started from A

What I want is this:

o---o---o---o  master
             \
              o---o---o  A
                       \
                        o B

What I did was:
1).

git checkout A
git rebase master

This resulted in a lot of conflicts which, after some significant time spent fixing, the following history emerged:

o---o---o---o  master
             \
              o---o---o  A

Which is exactly what I wanted.
(I don't know where B is right now)

2).
After this I did a lot of squashes and changed the order of commits on A, to make the history look like I want.

3).
Now, what I also want to do is:

git checkout B
git rebase A

However this doesn't seem to work and I don't know why. If I do git log I see the commits which were there before I did step 1.
Also, I get the same huge number of conflicts which I already solved at step 1. I spent significant time doing it, don't want to do it again.
This example suggested to use --onto, which I did:

git checkout B
git rebase --onto A

But this deletes the commit on B entirely and makes A and B point to the same commit i.e. the last one on A.

My question is: How can I effectively rebase B off A so that it looks like B started from A ? (which was actually true in the beginning).
My best guess is that I'm using --onto wrong. Or that I should use something else (like cherry-pick).

[Assistant]
Short answer to How can I effectively rebase B off A so that it looks like B started from A?
Assuming you want to move exactly one commit:
git rebase --onto A B~ B

If you want to move more then one commit use:
git rebase --onto A old_A B

The rest of the answer.
Your branch of B is still around (you can check it out), but its parent is still the exact commit object that A was before.
to see a graphical representation of this I use:
git log --graph --decorate --all

to see all branches and where they are with respect to each other.
What you originally had:
o---o---o---o  master
     \
      o---o---o  A
               \
                o B

What you have now:
o---o---o-----------o  master
     \               \
      o---o---o(B~)   o---o---o A
               \
                o B

In terms of using --onto, you need to have a starting point and an ending point.
use:
git rebase --onto [target] [rebasing stops] [rebasing head]
git rebase --onto A B~ B

And what you get:
o---o---o----------o  master
     \              \
      o---o---o      o---o---o A
            (old_A)           \
                               o B

[branch_name]~ indicates the parent commit of the branch.
The B~ is the branch that you do not want to change.  (It happens to be the old A)
Alternatively, if B was the only commit that had A as a parent, (i.e., B is the end of a chain of commits that branch off master) you could do
git checkout B
git rebase master
git checkout B~   # this is the commit before B (the A commit)
git branch -d A   # remove the old A branch (it was rebased, and so is now invalid
git branch A      # recreate the A branch on the commit that is based on the original A


[System] You are a helpful assistant.

[User]
Clone A Private Repository (Github)

I have a private repository on Github for a project I'm working on.  Until now I had only worked on my home desktop, but I just bought a laptop, and am trying to set it up so that I can work on the project from either computer, and push / pull changes.
I added a new SSH key to my Github account for the laptop, and was successful in cloning and making changes to a public test repo that I set up.  However, I couldn't clone the private repo.  Is there anything special I need to do in the command line in order to clone a private repo?  Do I need to set up a new GitHub account for my laptop and set myself up as a collaborator?
The command I used was git clone git://github.com/username/reponame.git

[Assistant]
Apr, 2022 Update:
You can clone a private repository from your account and you can also clone a private repository from organization if you're its owner or member.
*pat is PAT(Personal Access Token).
git clone https://<pat>@github.com/<your account or organization>/<repo>.git

To clone a private repository from your account or organization, you need to generate a PAT(Personal Access Token) on your Github account, and add it to the command above. *Organization doesn't have PAT generator.
This is how you generate a PAT on your Github account:
1, Go to "Settings":

2, Scroll down then go to "Developer settings":

3, Press "Personal access tokens" then press "Generate new token":

4, Fill "Note" then check "repo":
*If "repo" is not checked, you cannot clone a private repository.

5, Scroll down then press "Generate token":

6, Finally, a PAT is generated:

This is the command with the PAT generated above:
git clone https://[email protected]/<your account or organization>/<repo>.git


[System] You are a helpful assistant.

[User]
'git branch -av' showing remote branch that no longer exists
This is probably a dumb question, but I'm brand new to git and am seeing a remote branch that no longer exists.
$ git branch -a
* master
  remotes/origin/master
  remotes/origin/production

I don't believe the production branch exists remotely and can't figure out why it still shows locally. How can I delete/remove this branch? Here's what an attempt to remove it looks like:
$ git push origin :production

error: unable to push to unqualified destination: production
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
error: failed to push some refs to 'git@IP:puppet.git'

I can checkout the supposedly remote production branch but get this:
$ git checkout origin/production
Note: checking out 'origin/production'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at c323996... added powerdns module, no really

I have no clue what the heck I'm doing. Any help would be appreciated.

[Assistant]
You have to do:
git remote prune origin


[System] You are a helpful assistant.

[User] git-log - Show commit logs  -M[<n>]  --find-renames[=<n>]

[Assistant]
If generating diffs, detect and report renames for each commit.
For following files across renames while traversing history, see --follow .
If n is specified, it is a threshold on the similarity
index (i.e. amount of addition/deletions compared to the
file’s size). For example, -M90% means Git should consider a
delete/add pair to be a rename if more than 90% of the file
hasn’t changed.  Without a % sign, the number is to be read as
a fraction, with a decimal point before it.  I.e., -M5 becomes
0.5, and is thus the same as -M50% .  Similarly, -M05 is
the same as -M5% .  To limit detection to exact renames, use -M100% .  The default similarity index is 50%.


[System] You are a helpful assistant.

[User]
How should I use git diff for long lines?
I'm running git-diff on a file, but the change is at the end of a long line.
If I use cursor keys to move right, it loses colour-coding—and worse the lines don't line up—making it harder to track the change.
Is there a way to prevent that problem or to simply make the lines wrap instead?
I'm running Git 1.5.5 via mingw32.

[Assistant] Or if you use less as default pager just type -S while viewing the diff to reenable wrapping in less.


[System] You are a helpful assistant.

[User] git-merge - Join two or more development histories together  merge.suppressDest

[Assistant]
By adding a glob that matches the names of integration
branches to this multi-valued configuration variable, the
default merge message computed for merges into these
integration branches will omit "into <branch name>" from
its title. An element with an empty value can be used to clear the list
of globs accumulated from previous configuration entries.
When there is no merge.suppressDest variable defined, the
default value of master is used for backward compatibility.


[System] You are a helpful assistant.

[User] git-notes - Add or inspect object notes  copy

[Assistant]
Copy the notes for the first object onto the second object (defaults to
HEAD). Abort if the second object already has notes, or if the first
object has none (use -f to overwrite existing notes to the
second object). This subcommand is equivalent to: git notes add [-f] -C $(git notes list <from-object>) <to-object> In --stdin mode, take lines in the format <from-object> SP <to-object> [ SP <rest> ] LF on standard input, and copy the notes from each <from-object> to its
corresponding <to-object>.  (The optional <rest> is ignored so that
the command can read the input given to the post-rewrite hook.)


[System] You are a helpful assistant.

[User] git-log - Show commit logs  --sparse

[Assistant]
All commits that are walked are included. Note that without --full-history , this still simplifies merges: if
one of the parents is TREESAME, we follow only that one, so the other
sides of the merge are never walked.


[System] You are a helpful assistant.

[User] git - the stupid content tracker  git-push

[Assistant] Update remote refs along with associated objects


[System] You are a helpful assistant.

[User] git-rev-parse - Pick out and massage parameters  --shared-index-path

[Assistant]
Show the path to the shared index file in split index mode, or
empty if not in split-index mode.


[System] You are a helpful assistant.

[User] git - the stupid content tracker  GIT_PRINT_SHA1_ELLIPSIS (deprecated)

[Assistant]
If set to yes , print an ellipsis following an
(abbreviated) SHA-1 value.  This affects indications of
detached HEADs ( git-checkout ) and the raw
diff output ( git-diff ).  Printing an
ellipsis in the cases mentioned is no longer considered
adequate and support for it is likely to be removed in the
foreseeable future (along with the variable).


[System] You are a helpful assistant.

[User] git - the stupid content tracker  <old|new>-file

[Assistant]
are files GIT_EXTERNAL_DIFF can use to read the
contents of <old|new>,


[System] You are a helpful assistant.

[User] git-diff - Show changes between commits, commit and working tree, etc  Various ways to check your working tree

[Assistant]
$ git diff (1) $ git diff --cached (2) $ git diff HEAD (3) $ git diff AUTO_MERGE (4) Changes in the working tree not yet staged for the next commit. Changes between the index and your last commit; what you
would be committing if you run git commit without -a option. Changes in the working tree since your last commit; what you
would be committing if you run git commit -a Changes in the working tree you’ve made to resolve textual
conflicts so far.


[System] You are a helpful assistant.

[User]
Warning: push.default is unset; its implicit value is changing in Git 2.0
I've been using Git for a while now and have recently downloaded an update only to find this warning message come up when I try to push.
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

I can obviously set it to one of the values mentioned, but what do they mean? What's the difference between simple and matching?
If I change it on one client will I need to do anything on other clients that I share repos with?

[Assistant]
It's explained in great detail in the docs, but I'll try to summarize:

matching means git push will push all your local branches to the ones with the same name on the remote. This makes it easy to accidentally push a branch you didn't intend to.
simple means git push will push only the current branch to the one that git pull would pull from, and also checks that their names match. This is a more intuitive behavior, which is why the default is getting changed to this.

This setting only affects the behavior of your local client, and can be overridden by explicitly specifying which branches you want to push on the command line. Other clients can have different settings, it only affects what happens when you don't specify which branches you want to push.


[System] You are a helpful assistant.

[User] git-show - Show various types of objects  --cc

[Assistant]
Produce dense combined diff output for merge commits.
Shortcut for --diff-merges=dense-combined -p .


[System] You are a helpful assistant.

[User] git-log - Show commit logs  --alternate-refs

[Assistant]
Pretend as if all objects mentioned as ref tips of alternate
repositories were listed on the command line. An alternate
repository is any repository whose object directory is specified
in objects/info/alternates .  The set of included objects may
be modified by core.alternateRefsCommand , etc. See git-config .


[System] You are a helpful assistant.

[User]
Add git information to create-react-app
In development, I want to be able to see the build information (git commit hash, author, last commit message, etc) from the web. I have tried:

use child_process to execute a git command line, and read the result (Does not work because browser environment)
generate a buildInfo.txt file during npm build and read from the file (Does not work because fs is also unavailable in browser environment)
use external libraries such as "git-rev"

The only thing left to do seems to be doing npm run eject and applying https://www.npmjs.com/package/git-revision-webpack-plugin , but I really don't want to eject out of create-react-app. Anyone got any ideas?

[Assistant]
On a slight tangent (no need to eject and works in develop),
this may be of help to other folk looking to add their current git commit SHA into their index.html as a meta-tag by adding:
REACT_APP_GIT_SHA=`git rev-parse --short HEAD`

to the build script in the package.json and then adding (note it MUST start with REACT_APP... or it will be ignored):
<meta name="ui-version" content="%REACT_APP_GIT_SHA%">

into the index.html in the public folder.
Within react components, do it like this:
<Component>{process.env.REACT_APP_GIT_SHA}</Component>


[System] You are a helpful assistant.

[User]
How line ending conversions work with git core.autocrlf between different operating systems
I've read a lot of different questions and answers on Stack Overflow as well as git documentation on how the core.autocrlf setting works.
This is my understanding from what I've read:
Unix and Mac OSX (pre-OSX uses CR) clients use LF line endings.
Windows clients use CRLF line endings.
When core.autocrlf is set to true on the client, the git repository always stores files in LF line ending format and line endings in files on the client are converted back and forth on check out / commit for clients (i.e. Windows) that use non-LF line endings, no matter what format the line endings files are on the client (this disagrees with Tim Clem's definition - see update below).
Here is a matrix that tries to document the same for the 'input' and 'false' settings of core.autocrlf with question marks where I'm not sure of line ending conversion behavior.
My questions are:

What should the question marks be?
Is this matrix correct for the "non-question marks"?

I'll update the question marks from the answers as consensus appears to be formed.

                       core.autocrlf value
            true            input              false
----------------------------------------------------------
commit   |  convert           ?                  ?
new      |  to LF      (convert to LF?)   (no conversion?)

commit   |  convert to        ?                 no
existing |  LF         (convert to LF?)     conversion

checkout |  convert to        ?                 no
existing |  CRLF       (no conversion?)     conversion

I'm not really looking for opinions on the pros and cons of the various settings.  I'm just looking for data which makes it clear how to expect git to operate with each of the three settings.
--
Update 04/17/2012: After reading the article by Tim Clem linked by JJD in the comments, I have modified some of the values in the "unknown" values in the table above, as well as changing "checkout existing | true to convert to CRLF instead of convert to client".  Here are the definitions he gives, which are more clear than anything I've seen elsewhere:
core.autocrlf = false

This is the default, but most people are encouraged to change this
immediately. The result of using false is that Git doesn’t ever mess
with line endings on your file. You can check in files with LF or CRLF
or CR or some random mix of those three and Git does not care. This
can make diffs harder to read and merges more difficult. Most people
working in a Unix/Linux world use this value because they don’t have
CRLF problems and they don’t need Git to be doing extra work whenever
files are written to the object database or written out into the
working directory.

core.autocrlf = true

This means that Git will process all text files and make sure that
CRLF is replaced with LF when writing that file to the object database
and turn all LF back into CRLF when writing out into the working
directory. This is the recommended setting on Windows because it
ensures that your repository can be used on other platforms while
retaining CRLF in your working directory.

core.autocrlf = input

This means that Git will process all text files and make sure that
CRLF is replaced with LF when writing that file to the object
database. It will not, however, do the reverse. When you read files
back out of the object database and write them into the working
directory they will still have LFs to denote the end of line. This
setting is generally used on Unix/Linux/OS X to prevent CRLFs from
getting written into the repository. The idea being that if you pasted
code from a web browser and accidentally got CRLFs into one of your
files, Git would make sure they were replaced with LFs when you wrote
to the object database.

Tim's article is excellent, the only thing I can think of that is missing is that he assumes the repository is in LF format, which is not necessarily true, especially for Windows only projects.
Comparing Tim's article to the highest voted answer to date by jmlane shows perfect agreement on the true and input settings and disagreement on the false setting.

[Assistant]
The best explanation of how core.autocrlf works is found on the gitattributes man page, in the text attribute section.
This is how core.autocrlf appears to work currently (or at least since v1.7.2 from what I am aware):

core.autocrlf = true

Text files checked-out from the repository that have only LF characters are normalized to CRLF in your working tree; files that contain CRLF in the repository will not be touched
Text files that have only LF characters in the repository, are normalized from CRLF to LF when committed back to the repository. Files that contain CRLF in the repository will be committed untouched.

core.autocrlf = input

Text files checked-out from the repository will keep original EOL characters in your working tree.
Text files in your working tree with CRLF characters are normalized to LF when committed back to the repository.

core.autocrlf = false

core.eol dictates EOL characters in the text files of your working tree.
core.eol = native by default, which means working tree EOLs will depend on where git is running: CRLF on a Windows machine, or LF in *nix.
Repository gitattributes settings determines EOL character normalization for commits to the repository (default is normalization to LF characters).

I've only just recently researched this issue and I also find the situation to be very convoluted. The core.eol setting definitely helped clarify how EOL characters are handled by git.


[System] You are a helpful assistant.

[User] git - the stupid content tracker  git-hook

[Assistant] Run git hooks


[System] You are a helpful assistant.

[User]
How to prevent phabricator from eating my commit history

Here is the scenario that is pretty much annoying me.
Jack works in foobar a software house, Jack is a Working Programmer, he loves coding and commits frequently. Paul who is jack's manager tells him that we are going to start using a new code review tool, phabricator. Jack complies, Jack creates a local branch and starts working. He adds features and commits to his local branch very frequently. Now at the end of the day he sends a phabricator request.
arc diff development

John who is jacks team member reviews his code and accepts his changes.
Now Jack opens the terminal and moves to his repository directory.
Jack types the following command to close the revision and merge his code with the development branch.
arc land --onto development

He sees the following message
Landing current branch 'feature-awesome-features'.
Switched to branch development. Updating branch...
The following commit(s) will be landed:

b2ff76e  Added the foo to bar
33f33ba  Added a really important check which can destroy the project or save it
31a4c9a Added that new awesome feature
8cae3bf rewrote that awful code john wrote
bc54afb  bug fixes

Switched to branch feature-awesome-features. Identifying and merging...
Landing revision 'D1067: Added the awesome feature'...
Rebasing feature-awesome-features onto development
Already up-to-date.
Pushing change...

Now jack opens Github to see his code , his beautiful commits. but what he sees is pure horror all of his commits have been replaced by a single commit which basically says something like this
Summary: Added the awesome feature

Test Plan:  do foo bar testing

Reviewers: John

Reviewed By: John

CC: Paul

Differential Revision: http://phabricator.foobar.com/D1067

Now jack is sad, because he wants to see all of his commits, jack thinks that this commit makes him look like The Hoarder which he is not. He wants to fix this so he goes to ask a question on stackoverflow.
That how may he prevent phabricator from eating his commit history.

[Assistant]
asherkin's answer explains the rationale for this behavior, and why this is the default.
If you don't find that argument compelling, you can use the --merge flag to arc land to perform --no-ff merges instead of --squash merges. These merges will not destroy local commits.
If you set history.immutable to true in your .arcconfig, arc land will --no-ff merge by default.
You can also use raw git commands if you don't like the behavior of arc land; it is provided only for convenience.
In your example, we recommend creating five separate reviews -- there are multiple different ideas being implemented, and they are not related and seem easily separable. See Writing Reviewable Code. Combining bugfixes, style changes and new features into one change is hoarding.


[System] You are a helpful assistant.

[User] git-rebase - Reapply commits on top of another base tip  Hard case: The changes are not the same.

[Assistant]
This happens if the subsystem rebase had conflicts, or used --interactive to omit, edit, squash, or fixup commits; or
if the upstream used one of commit --amend , reset , or
a full history rewriting command like filter-repo .


[System] You are a helpful assistant.

[User]
Is there a migration tool from CVS to Git?
I intend to switch over from CVS to Git.
In the case of SVN, there seems to be cvs2svn.  Is there a similar tool to easily migrate from CVS to Git?

[Assistant]
The only tool that has incremental import seems to be git-cvsimport. If you want to convert (migrate) from CVS to Git, the best solution for now seems to be mentioned above cvs2git mode of cvs2svn.
See also Interfaces Frontends And Tools page on Git wiki, section about interaction with other revision control systems.


[System] You are a helpful assistant.

[User]
Resolve conflicts using remote changes when pulling from Git remote
I'm trying to pull code from my GitHub repo onto my server, but the pull keeps failing because of merge conflicts. I don't want to keep any of the changes that may have occurred on my local server since the last pull.
So is there a way I can force Git to overwrite with whatever version is in GitHub, rather than bother me about conflicts?

[Assistant]
If you truly want to discard the commits you've made locally, i.e. never have them in the history again, you're not asking how to pull - pull means merge, and you don't need to merge. All you need do is this:
# fetch from the default remote, origin
git fetch
# reset your current branch (master) to origin's master
git reset --hard origin/master

I'd personally recommend creating a backup branch at your current HEAD first, so that if you realize this was a bad idea, you haven't lost track of it.
If on the other hand, you want to keep those commits and make it look as though you merged with origin, and cause the merge to keep the versions from origin only, you can use the ours merge strategy:
# fetch from the default remote, origin
git fetch
# create a branch at your current master
git branch old-master
# reset to origin's master
git reset --hard origin/master
# merge your old master, keeping "our" (origin/master's) content
git merge -s ours old-master


[System] You are a helpful assistant.

[User] git-ls-files - Show information about files in the index and the working tree  --exclude-per-directory=<file>

[Assistant]
Read additional exclude patterns that apply only to the
directory and its subdirectories in <file>.  If you are
trying to emulate the way Porcelain commands work, using
the --exclude-standard option instead is easier and more
thorough.


[System] You are a helpful assistant.

[User] git - the stupid content tracker  git-ls-remote

[Assistant] List references in a remote repository


[System] You are a helpful assistant.

[User]
Make the current commit the only (initial) commit in a Git repository?

I  currently have a local Git repository, which I push to a Github repository.
The local repository has ~10 commits, and the Github repository is a synchronised duplicate of this.
What I'd like to do is remove ALL the version history from the local Git repository, so the current contents of the repository appear as the only commit (and therefore older versions of files within the repository are not stored).
I'd then like to push these changes to Github.
I have investigated Git rebase, but this appears to be more suited to removing specific versions.
Another potential solution is to delete the local repo, and create a new one - though this would probably create a lot of work!
ETA: There are specific directories / files that are untracked - if possible I would like to maintain the untracking of these files.

[Assistant]
Here's the brute-force approach. It also removes the configuration of the repository.
Note: This does NOT work if the repository has submodules! If you are using submodules, you should use e.g. interactive rebase
Step 1: remove all history (Make sure you have a backup, this cannot be reverted)
cat .git/config  # save your <github-uri> somewhere
rm -rf .git

Step 2: reconstruct the Git repo with only the current content
Before step 2 if you have not set up init.defaultBranch configuration then, please do it via git config --global init.defaultBranch <branch-name> you may choose main as <branch-name> in the current example
git init
git add .
git commit -m "Initial commit"

Step 3: push to GitHub.
git remote add origin <github-uri>
git push -u --force origin main


[System] You are a helpful assistant.

[User]
How to clone all repos at once from GitHub?
I have a company GitHub account and I want to back up all of the repositories within, accounting for anything new that might get created for purposes of automation. I was hoping something like this:
git clone [email protected]:company/*.git

or similar would work, but it doesn't seem to like the wildcard there.
Is there a way in Git to clone and then pull everything assuming one has the appropriate permissions?

[Assistant]
Simple script using GitHub CLI (no API keys)
Here's a simple solution using the official GitHub CLI tool, gh - no need for API keys and can handle up to 4,000 private repos.
First time only: log in with gh for private repos, and follow the prompts:
gh auth login

Now you can clone thousands of repos under a new ./myorgname folder. Replace myorgname with your org name:
gh repo list myorgname --limit 4000 | while read -r repo _; do
  gh repo clone "$repo" "$repo"
done

The default limit is 30.
This should work on Mac or Linux.
For Windows:

Run this bash script in Git Bash, part of Git for Windows - or in WSL
Or try the comment here by @Karson for a similar script in PowerShell

Setup
To get the GitHub CLI tool:

Mac - brew install gh
Linux or Windows - see GitHub install guide

Future proofing: the GitHub CLI tool will be supported long-term as and when the GitHub API changes.  Some older answers here don't work any more due to this.
Optional: update existing checkouts
To update repo folders already on disk, as well as clone new repos, the script needs to check for failure of the gh repo clone, like this:
gh repo list myorgname --limit 1000 | while read -r repo _; do
  gh repo clone "$repo" "$repo" -- -q 2>/dev/null || (
    cd "$repo"
    # Handle case where local checkout is on a non-main/master branch
    # - ignore checkout errors because some repos may have zero commits,
    # so no main or master
    git checkout -q main 2>/dev/null || true
    git checkout -q master 2>/dev/null || true
    git pull -q
  )
done

Tips

Don't want to create repos in the ./myorgname folder?  Drop the second "$repo" argument to gh repo clone to create them in the current directory

To filter results:

--no-archived - omit archived repositories
--source - show only non-forks

Tip: Handling thousands of repos
This script works with up to about 4,000 repos - see @Ryan Fisher comment below, and comment with your results.
The gh repo list command uses the GitHub Search API, which is paginated when returning many results.  There is a limit of 4,000 on the number of repos that can be searched.
To work around any limits:

check the gh repo list command is returning what you expect
make sure you are omitting archived and forked repos
see gh repo list --help to filter by language, topic, etc

Or you can use a different answer (based on API requests) that replaces the gh repo list command or the whole script.
Tip: Faster cloning for many repos
If you are cloning a large number of repos, you can speed up this script with GNU parallel.
gh repo list <ORG_NAME> --limit <LIMIT> --json nameWithOwner --jq '.[].nameWithOwner' | \
   parallel -j<JOBS> gh repo clone

This uses gh's internal jq library, rather than a standalone jq.
If you are using the "update existing checkouts" option above, you will need to merge this into the above script - perhaps putting the loop contents into a separate bash -c "..." command under parallel.
You can also use xargs -P to clone repos in parallel - see this answer.
Background

GitHub CLI login doc
Script commands above were derived from an issue comment and gist by davegallant
GNU parallel script contributed by @RyanFisher


[System] You are a helpful assistant.

[User] git-fetch - Download objects and refs from another repository

[Assistant]
SECURITY The fetch and push protocols are not designed to prevent one side from
stealing data from the other repository that was not intended to be
shared. If you have private data that you need to protect from a malicious
peer, your best option is to store it in another repository. This applies
to both clients and servers. In particular, namespaces on a server are not
effective for read access control; you should only grant read access to a
namespace to clients that you would trust with read access to the entire
repository. The known attack vectors are as follows: The victim sends "have" lines advertising the IDs of objects it has that
are not explicitly intended to be shared but can be used to optimize the
transfer if the peer also has them. The attacker chooses an object ID X
to steal and sends a ref to X, but isn’t required to send the content of
X because the victim already has it. Now the victim believes that the
attacker has X, and it sends the content of X back to the attacker
later. (This attack is most straightforward for a client to perform on a
server, by creating a ref to X in the namespace the client has access
to and then fetching it. The most likely way for a server to perform it
on a client is to "merge" X into a public branch and hope that the user
does additional work on this branch and pushes it back to the server
without noticing the merge.) As in #1, the attacker chooses an object ID X to steal. The victim sends
an object Y that the attacker already has, and the attacker falsely
claims to have X and not Y, so the victim sends Y as a delta against X.
The delta reveals regions of X that are similar to Y to the attacker.


[System] You are a helpful assistant.

[User]
Notifications for new Github project releases? [closed]

Closed. This question is seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. It does not meet Stack Overflow guidelines. It is not currently accepting answers.

 We don’t allow questions seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. You can edit the question so it can be answered with facts and citations.

Closed 6 years ago.

                        Improve this question

I'm using a library from a Github project. Is there some way to set up a notification for new project releases?
For example, I want to know when a new release appears here
I know I can be notified on every issue update, but that's not what I'm looking for. Though I see some projects are using that as a way to keep people notified

[Assistant]
Don't know about email, but you can subscribe to RSS Atom feed with releases:
https://github.com/dropbox/dropbox-js/releases.atom
or tags:
https://github.com/dropbox/dropbox-js/tags.atom

EDIT:
To get notification via email you can use Sibbell.com or RSS-to-email service like Blogtrottr.


[System] You are a helpful assistant.

[User]
How to automatically resolve a Git conflict by taking the version in the current branch?
Let's suppose that I get a merge conflict on foo/bar.txt when running this:
$ git checkout A
$ git merge B

I'd like to automatically resolve the conflict by taking foo/bar.txt from branch A. (I know what I'm doing, and I do need this. The version in branch B is wrong, and I don't care about losing changes in the working tree in this case.) It seems that I can do it by running these commands:
$ git reset    foo/bar.txt
$ git checkout foo/bar.txt

Is there a simpler, single-command solution?
Unfortunately these commands change foo/bar.txt even if there is no conflict, and I don't want that. If there is no conflict, I want want to keep foo/bar.txt in whatever state git merge B has left it.
So I need a Unix shell command, which would detect if there is a conflict in foo/bar.txt, and if there is, it would resolve the conflict by taking the version of foo/bar.txt from the current branch. It wouldn't do anything else, i.e. it wouldn't modify other files, it wouldn't commit the changes, and it wouldn't change foo/bar.txt if there is no conflict in that file.

[Assistant]
You can specify the merge strategy option ours to the recursive (the default) merge strategy. It will perform a normal merge, but in case of conflicting hunks, it will choose the version of the current branch (i.e. ours).
git checkout A
git merge -X ours B

Note that this is very different from -s ours, which selects a different merge strategy. Doing so would throw away all changes of the other branch and only keep our version. Refer to How do I 'overwrite', rather than 'merge', a branch on another branch in Git? for more details.


[System] You are a helpful assistant.

[User] git-diff - Show changes between commits, commit and working tree, etc  git diff [<options>] --no-index [--] <path> <path>

[Assistant]
This form is to compare the given two paths on the
filesystem.  You can omit the --no-index option when
running the command in a working tree controlled by Git and
at least one of the paths points outside the working tree,
or when running the command outside a working tree
controlled by Git. This form implies --exit-code .


[System] You are a helpful assistant.

[User] git-fast-import - Backend for fast Git data importers  --big-file-threshold=<n>

[Assistant]
Maximum size of a blob that fast-import will attempt to
create a delta for, expressed in bytes.  The default is 512m
(512 MiB).  Some importers may wish to lower this on systems
with constrained memory.


[System] You are a helpful assistant.

[User]
How to change the starting point of a branch?

Usually I create a branch by running a command like git checkout -b [branch-name] [starting-branch]. In one case, I forgot to include the starting-branch, and now I want to correct it. How do I do so after the branch has already been created?

[Assistant]
The short answer is that once you have some commits, you want to git rebase them, using the long form of git rebase: git rebase --onto newbase upstream.  To find out how to identify each of these, see the (very) long answer below.  (Unfortunately, it got a bit out of hand and I do not have time to shorten it.)
The problem you have here is that in Git, branches don't have a "starting point"—at least, not in any useful way.
The term "branch", in Git, is ambiguous
The first issue here is that, in Git, the word "branch" has at least two distinct meanings.  Usually, when we talk loosely about "the branch", it's clear from context whether we mean the branch name—the thing that's a word like master or develop or feature-X—or the thing that I call "branch ancestry" or "branch structure", or more informally, a "DAGlet".1  See also What exactly do we mean by "branch"?
In this particular case, unfortunately, you mean both of these, at the same time.

1The term DAG is short for Directed Acyclic Graph, which is what the commit graph is: a set of vertices or nodes, and directional (from child to parent) edges, such that there are no cycles through the directed edges from any node back to itself.  To this I simply add the "-let" diminutive suffix.  The resulting word has a happy resemblance to the word aglet, plus a certain assonance with the word "dagger", making it sound slightly dangerous: "Is this a DAGlet which I see before me?"
Draw your commit graph
Whenever you need to grapple with these issues, it helps to draw a graph of what you have now, or at least some useful subset of what you have now.  There are of course many ways to draw this (see that linked question for several options, including some bad ones :-) ), but in plain text in a StackOverflow answer, I generally draw them like this:
...--o--o--o           <-- master
         \
          o--o--o--o   <-- develop

The round o nodes represent commits, and the branch names master and develop point to one specific tip commit on each branch.
In Git, every commit points back to its parent commit(s), and this is how Git forms branch structures.  By "branch structures", I mean here particular subsets of the overall ancestry part of the graph, or what I call the DAGlets.  The name master points to the tip-most commit of the master branch, and that commit points back (leftward) to another commit that is the previous commit on the branch, and that commit points leftward again, and so on.
When we need to talk about specific commits within this graph, we can use their actual names, which are the big ugly 40-character hashes that identify each Git object.  Those are really clumsy though, so what I do here is replace the little round os with uppercase letters:
...--A--B--C           <-- master
         \
          D--E--F--G   <-- develop

and now it's easy to say, e.g., that the name master points to commit C, and C points to B, and B points to A, which points back to more history that we don't really care about and hence just left as ....
Where does a branch begin?
Now, it's perfectly obvious, to you and me, based on this graph drawing, that branch develop, whose tip commit is G, starts at commit D.  But it's not obvious to Git—and if we draw the same graph a little differently, it may be less obvious to you and me too.  For instance, look at this drawing:
          o             <-- X
         /
...--o--o--o--o--o--o   <-- Y

Obviously branch X has just the one commit and the main line is Y, right?  But let's put some letters in:
          C             <-- X
         /
...--A--B--D--E--F--G   <-- Y

and then move Y down a line:
          C            <-- X
         /
...--A--B
         \
          D--E--F--G   <-- Y

and then look what happens if we move C down to the main line, and realize that X is master and Y is develop?  Which branch is commit B on after all?
In Git, commits may be on many branches simultaneously; DAGlets are up to you
Git's answer to this dilemma is that commits A and B are on both branches.  The beginning of branch X is way off to the left, in the ... part.  But so is the beginning of branch Y.  As far as Git is concerned, a branch "starts" at whatever root commit(s) it can find in the graph.
This is important to keep in mind in general.  Git has no real concept of where a branch "started", so we wind up having to give it extra information.  Sometimes that information is implied, and sometimes it is explicit.  It's also important, in general, to remember that commits are often on many branches—so instead of specifying branches, we usually specify commits.
We just often use branch names to do this.  But if we give Git just a branch name, and tell it to find all the ancestors of the tip commit of that branch, Git goes all the way back in history.
In your case, if you write the name develop and ask Git to select that commit and its ancestors, you get commits D-E-F-G (which you wanted) and commit B, and commit A, and so on (which you didn't).  The trick, then, is to somehow identify which commits you don't want, along with which commits you do.
Normally we use the two-dot X..Y syntax
With most Git commands, when we want to select some particular DAGlet, we use the two-dot syntax described in gitrevisions, such as master..develop.  Most2 Git commands that work on multiple commits treat this as: "Select all commits starting from the tip of the develop branch, but then subtract from that set, the set of all commits starting from the tip of the master branch."  Look back at our graph drawing of master and develop: this says "do take commits starting from G and working backwards"—which gets us too many, since it includes commits B and A and earlier—"but exclude commits starting from C and working backwards."  It's that exclude part that gets us what we want.
Hence, writing master..develop is how we name commits D-E-F-G, and have Git compute that automatically for us, without having to first sit down and draw out a big chunk of the graph.

2Two notable exceptions are git rebase, which is in its own section just below, and git diff.  The git diff command treats X..Y as simply meaning X Y, i.e., it effectively just ignores the two dots entirely.  Note that this has a very different effect than set subtraction: in our case, git diff master..develop simply diffs the tree for commit C against the tree for commit G, even though master..develop never has commit C in the first set.
In other words, mathematically speaking, master..develop is normally ancestors(develop) - ancestors(master), where the ancestors function includes the specified commit, i.e., is testing ≤ rather than just <.  Note that ancestors(develop) does not include commit C at all.  The set subtraction operation simply ignores the presence of C in the set ancestors(master).  But when you feed this to git diff, it does not ignore C: it does not diff, say, B against G.  While that might be a reasonable thing to do, git diff instead steals the three-dot master...develop syntax to accomplish this.
Git's rebase is a little bit special
The rebase command is almost always used to move3 one of these DAGlet commit-subsets from one point in the graph to another.  In fact, that's what rebase is, or was originally anyway, defined to do.  (Now it has a fancy interactive rebase mode, which does this and a bunch more history editing operations.  Mercurial has a similar command, hg histedit, with a slightly better name, and much tighter default semantics.4)
Since we always (or almost always) want to move a DAGlet, git rebase builds in this subset selection for us.  And, since we always (or almost always) want to move the DAGlet to come just after the tip of some other branch, git rebase defaults to choosing the target (or --onto) commit using a branch name, and then uses that same branch name in the X..Y syntax.5

3Technically, git rebase actually copies commits, rather than moving them.  It has to, because commits are immutable, like all Git's internal objects.  The true name, the SHA-1 hash, of a commit is a checksum of the bits making up the commit, so any time you change anything—including something as simple as the parent ID—you have to make a new, slightly-different, commit.
4In Mercurial, quite unlike Git, branches really do have starting points, and—more important for histedit—commits record their phase: secret, draft, or published.  History editing readily applies to secret or draft-phase commits, and not so much to published commits.  This is true of Git as well, but since Git has no concept of commit phases, Git's rebase must use these other techniques.
5Technically the <upstream> and --onto arguments can just be raw commit IDs.  Note that 1234567..develop works just fine as a range selector, and you can rebase --onto 1234567 to place the new commits after commit 1234567.  The only place that git rebase truly needs a branch name is for the name of the current branch, which it normally just reads from HEAD anyway.  However, we usually want to use a name, so that's how I describe it all here.

That is, if we're currently on branch develop, and in this situation that we drew before:
...--A--B--C           <-- master
         \
          D--E--F--G   <-- develop

we probably just want to move the D-E-F-G chain onto the tip of master, to get this:
...--A--B--C              <-- master
            \
             D'-E'-F'-G'  <-- develop

(The reason I changed the names from D-E-F-G to D'-E'-F'-G' is that rebase is forced to copy the original commits, rather than actually moving them.  The new copies are just as good as the originals, and we can use the same single letter name, but we should at least note, however vaguely, that these are in fact copies.  That's what the "prime" marks, the ' characters, are for.)
Because this is what we usually want, git rebase will do this automatically if we just name the other branch.  That is, we're on develop now:
$ git checkout develop

and we want to rebase commits that are on branch develop and are not on master, moving them to the tip of master.  We might express this as git somecmd master..develop master, but then we would have to type the word master twice (such a dreadful fate).  So instead, Git's rebase infers this when we just type in:
$ git rebase master

The name master becomes the left side of the two-dot .. DAGlet selector, and the name master also becomes the target of the rebase; and Git then rebases D-E-F-G onto C.  Git gets our branch's name, develop, by reading out the current branch name.  In fact, it uses a shortcut, which is that when you need the current branch name, you can normally just write HEAD instead.  So master..develop and master..HEAD mean the same thing, because HEAD is develop.
Git's rebase calls this name the <upstream>.  That is, when we say git rebase master, Git claims, in the documentation, that master is the <upstream> argument to git rebase.  The rebase command then operates on commits in <upstream>..HEAD, copying them after whatever commit is in <upstream>.
This is going to become a problem for us soon, but for now, just make note of it.
(Rebase also has the sneaky, but desirable, side feature of omitting any of the D-E-F-G commits that sufficiently resembles commit C.  For our purposes we can ignore this.)
What's wrong with the other answer to this question
In case the other answer gets deleted, or becomes one of several other answers, I'll summarize it here as "use git branch -f to move the branch label."  The flaw in the other answer—and, perhaps more importantly, precisely when it's a problem—becomes obvious once we draw our graph DAGlets.
Branch names are unique, but tip commits are not necessarily so
Let's take a look at what happens when you run git checkout -b newbranch starting-point.  This asks Git to root around in the current graph for the given starting-point, and make the new branch label point to that specific commit.  (I know I said above that branches don't have a starting point.  This is still mostly true: we're giving the git checkout command a starting point now, but Git is about to set it and then, crucially, forget it.)  Let's say that starting-point is another branch name, and let's draw a whole bunch of branches:
          o--o--o--o     <-- brA
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- brC
                 \
                  o--o   <-- brD

Since we have four branch names, we have four branch tips: four branch-tip commits, identified by the names brA through brD.  We pick one and make a new branch name newbranch that points to the same commit as one of these four.  I have arbitrarily picked brA here:
          o--o--o--o     <-- brA, newbranch
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- brC
                 \
                  o--o   <-- brD

We now have five names, and five ... er, four? ... well, some tip commits.  The tricky bit is that brA and newbranch both point to the same tip commit.
Git knows—because git checkout sets it—that we're now on newbranch.  Specifically Git writes the name newbranch into HEAD.  We can make our drawing a bit more accurate by adding this information:
          o--o--o--o     <-- brA, HEAD -> newbranch
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- brC
                 \
                  o--o   <-- brD

At this point, the four commits that used to be only on branch brA are now on both brA and newbranch.  And, by the same token, Git no longer knows that newbranch starts at the tip of brA.  As far as Git is concerned, both brA and newbranch contain those four commits and all the earlier ones too, and both of them "start" way back in time somewhere.
When we make new commits, the current name moves
Since we're on branch newbranch, if we make a new commit now, the new commit's parent will be the old tip commit, and Git will adjust the branch name newbranch to point to the new commit:
                     o   <-- HEAD -> newbranch
                    /
          o--o--o--o     <-- brA
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- brC
                 \
                  o--o   <-- brD

Note that none of the other labels moved: the four "old" branches stay put, only the current (HEAD) branch changes.  It changes to accommodate the new commit we just made.
Note that Git continues to have no idea that branch newbranch "started" at brA.  It's just the case, now, that newbranch contains one commit that brA does not, plus the four commits that they both contain, plus all those earlier commits.
What git branch -f does
Using git branch -f lets us move a branch label.  Let's say, for whatever mysterious reason, we don't want branch label brB to point where it does in our current drawing.  Instead, we want it to point to the same commit as brC.  We can use git branch -f to change the place to which brB points, i.e., to move the label:
$ git branch -f brB brC

                     o   <-- HEAD -> newbranch
                    /
          o--o--o--o     <-- brA
         /
...--o--o--o--o--o--o    [abandoned]
            \
             o--o--o     <-- brC, brB
                 \
                  o--o   <-- brD

This makes Git "forget" or "abandon" those three commits that were only on brB before.  That's probably a bad idea—why did we decide to do this strange thing?—so we probably want to put brB back.
Reflogs
Fortunately, "abandoned" commits are normally remembered in what Git calls reflogs.  Reflogs use an extended syntax, name@{selector}.  The selector part is usually either a number or date, such as brB@{1} or brB@{yesterday}.  Every time Git updates a branch name to point to some commit, it writes a reflog entry for that branch, with the pointed-to commit's ID, a time-stamp, and an optional message.  Run git reflog brB to see these.  The git branch -f command wrote the new target as brB@{0}, bumping up all the old numbers, so now brB@{1} names the previous tip commit.  So:
$ git branch -f brB 'brB@{1}'
    # you may not need the quotes, 'brB@{...}' --
    # I need them in my shell, otherwise the shell
    # eats the braces.  Some shells do, some don't.

will put it back (and also renumber all the numbers again: each update replaces the old @{0} and makes it @{1}, and @{1} becomes @{2}, and so on).
Anyway, suppose that we do our git checkout -b newbranch while we're on brC, and fail to mention brA.  That is, we start with:
          o--o--o--o     <-- brA
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- HEAD -> brC
                 \
                  o--o   <-- brD

and run git checkout -b newbranch.  Then we get this:
          o--o--o--o     <-- brA
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- brC, HEAD -> newbranch
                 \
                  o--o   <-- brD

If we meant to make newbranch point to commit brA, we can in fact do that right now, with git branch -f.  But let's say we make a new commit before realizing that we made newbranch start at the wrong point.  Let's draw it in:
          o--o--o--o     <-- brA
         /
...--o--o--o--o--o--o    <-- brB
            \
             o--o--o     <-- brC
                 \  \
                 |   o   <-- HEAD -> newbranch
                 \
                  o--o   <-- brD

If we use git branch -f now, we'll abandon—lose—the commit we just made.  What we want instead is to rebase it, onto the commit that branch brA points-to.
A simple git rebase copies too much
What if, instead of using git branch -f, we use git rebase brA?  Let's analyze this using—what else—our DAGlets.  We start with the above drawing above, with the extended leg going out to brD, though in the end we get to ignore that leg, and with the section going to brB, most of which we also get to ignore.  What we don't get to ignore is all that stuff in the middle, that we get by tracing the lines back.
The git rebase command, in this form, will use brA..newbranch to pick commits to copy.  So, starting with the whole DAGlet, let's mark (with *) all the commits that are on (or contained in) newbranch:
          o--o--o--o     <-- brA
         /
...--*--*--*--o--o--o    <-- brB
            \
             *--*--*     <-- brC
                 \  \
                 |   *   <-- HEAD -> newbranch
                 \
                  o--o   <-- brD

Now, let's un-mark (with x) all the commits that are on (or contained in) brA:
          x--x--x--x     <-- brA
         /
...--x--x--*--o--o--o    <-- brB
            \
             *--*--*     <-- brC
                 \  \
                 |   *   <-- HEAD -> newbranch
                 \
                  o--o   <-- brD

Whatever remains—all the * commits—are the ones that git rebase will copy.  That's way too many!
We need to get git rebase to copy just the one commit.  What this means is that for the <upstream> argument, we need to give git rebase the name brC.6  That way, Git will use brC..HEAD to select the commits to copy, which will be just the one commit we need to copy.
But—alas!—now we have a big problem, because git rebase wants to copy the commit to a point right after the <upstream> we just gave it.  That is, it wants to copy the commits to just after brC.  That's where the commits are now!  (Well, the one commit is.)  So this is no good at all!
Fortunately, git rebase has an escape hatch, specifically the --onto argument.  I mentioned this several times before, but now is when we need it.  We want the copies to go right after brA, so that's what we will supply as the --onto argument.  Git's rebase uses the <upstream> by default, but if we give it an --onto, it uses that instead.  So:
$ git branch   # just checking...
  brA
  brB
  brC
  brD
  master
* newbranch

OK, good, we're still on newbranch.  (Note that git status works here too, and if you use one of those fancy shell prompt setup things, you can even get your current branch name to be in your prompt, so that you don't need to run git status as often.)
$ git rebase --onto brA brC

Now Git will select commits in brC..HEAD, which is the right set of commits to copy, and copy them right after the tip of brA, which is the right place to copy them to.  Once the copies are all done, Git will abandon the original commits7 and make the name newbranch point to the new, tip-most, copied commit.
Note that this works even if you have no new commits on the new branch.  This is the one case where git branch -f also works.  When there are no commits, this git rebase carefully copies all zero of them :-) and then makes the name, newbranch, point to the same commit as brA.  Hence git branch -f is not always wrong; but git rebase is always right—albeit somewhat clumsy: you must identify both the <upstream> and the --onto points manually.

6Or, as we noted in an earlier footnote, we can give git rebase the ID of the commit to which the name brC points.  Either way, we have to supply this as the upstream argument.
7Except, of course, reflog entry newbranch@{1} will remember the old, now-abandoned, tip commit.  Additional reflog entries for newbranch may remember yet more commits, and remembering the tip commit suffices to keep all its ancestors alive.  The reflog entries eventually expire—after 30 days for some cases, and 90 for others, by default—but this gives you up to a month or so, by default, to recover from mistakes.


[System] You are a helpful assistant.

[User] git-config - Get and set repository or global options  push.pushOption

[Assistant]
When no --push-option=<option> argument is given from the
command line, git push behaves as if each <value> of
this variable is given as --push-option=<value> . This is a multi-valued variable, and an empty value can be used in a
higher priority configuration file (e.g. .git/config in a
repository) to clear the values inherited from a lower priority
configuration files (e.g. $HOME/.gitconfig ). Example:

/etc/gitconfig
  push.pushoption = a
  push.pushoption = b

~/.gitconfig
  push.pushoption = c

repo/.git/config
  push.pushoption =
  push.pushoption = b

This will result in only b (a and c are cleared).


[System] You are a helpful assistant.

[User] git-fetch - Download objects and refs from another repository  -p  --prune

[Assistant]
Before fetching, remove any remote-tracking references that no
longer exist on the remote.  Tags are not subject to pruning
if they are fetched only because of the default tag
auto-following or due to a --tags option.  However, if tags
are fetched due to an explicit refspec (either on the command
line or in the remote configuration, for example if the remote
was cloned with the --mirror option), then they are also
subject to pruning. Supplying --prune-tags is a shorthand for
providing the tag refspec. See the PRUNING section below for more details.


[System] You are a helpful assistant.

[User]
Git: rename directory (case-only) on Windows
I want to rename a directory versioned by Git on a Windows system (change the case of the directory name):
$ git mv docs DOCS
Rename from 'docs' to 'DOCS/docs' failed. Should I try again? (y/n) n
fatal: renaming 'docs' failed: Permission denied

I've also tried with the force-option - but with the same result:
$ git mv --force docs DOCS
Rename from 'docs' to 'DOCS/docs' failed. Should I try again? (y/n) n
fatal: renaming 'docs' failed: Permission denied

For some reason Git fails because it thinks DOCS already is an existing directory and the directory should be moved inside it. I know that I can rename & commit using a temporary directory name and then rename & amend-commit to the final name, but isn't there a way to tell Git that I don't want to move inside any other directory?

[Assistant]
You can try to do it in 2 step.
$ git mv docs DOCS2
$ git mv DOCS2 DOCS

it will work