94 skills found · Page 2 of 4
danielSanchezQ / Rusty ResultsRust-inspired Option and Result types. Pattern matching ready!
hrimov / Flask TemplateFlask project template with several architectural pattern options
westonplatter / Ta ScannerScanner that finds patterns in stocks/options/futures and discerns future risk/reward. Ie, money ball engine.
cecgeology / USGS FGDCUSGS Lithology Patterns for QGIS as SVG with option to modify colors
arun-mansa / TradingbotAutomatically buy option from iqoption based on specified patterns
zajrik / Option ResultA lightweight Dart library for Rust-like Option/Result types and associated pattern matching
AndyOGo / Node Sync GlobSynchronize files and folders locally by glob patterns, watch option included.
krshrimali / CPP File ManagerA C++ File Manager library, to load files in a directory with options to exclude extensions with patterns. Also available as cross platform binary.
lukemorales / FunkciaEncode failure and absence of value in TypeScript
jfischoff / Partial Options Monoid PatternA demo of the Partial Options Monoid pattern
quasiblob / ComfyUI EsesImageTransformApply 2D transformations to images and masks within ComfyUI. Zoom, position, scale, flip, rotate, squash and stretch the input content. Tile images to create patterns (supports alpha channels). Fill options for managing canvas areas exposed by transformations. Apply masks to RGB images and invert mask inputs or outputs. No extra dependencies.
payMeQuiz / PayMe ProjectpayMe is a technical solution initiated by some concerned Nigerians aimed to catalyze the innate desire in humans to fairly compete in an intellectual learning exercise. payMe is structured to more than engage users to learn but to incentivize users to be compelled to strive to achieve desired results on set targets. That in fact is the excelling value of payMe over competitions. payMe is originally a web2 play-to-earn (P2E) gaming application upgraded to a hybrid platform by the adoption of the platform's native utility token for incentivizing success among the quizzers. Play-to-earn (P2E) games are online games that guarantee rewards with real-world value to players for completing given task in a contest with other players. It comes with different structure and rewarding system. In the blockchain ecosystem, these rewards can be in the form of in-game assets like crypto tokens, virtual land, as well as the game assets (weapons, tools etc.) and other NFTs. The advent of web3 and its decentralized nature made it possible for players to buy, transfer and sell these in-game assets, outside of the games's traditional platform in exchange for real money. payMe is designed to encourage knowledge development using incentivization of success. payMe serve as cognitive behavioral therapy (CBT) to users who are psychogically affected by the disturbing examination malpractice permitted in the system, with the learn to earn functionality that catalyzes users desire to aspire to be the best in a transparent and meritorious form of testing knowledgeability. The transparent, honest, and undisputed fairness in determination of examinations success, aim also to promote hardwork as valuable asset to success as against luck dependency, in a society that eligizes game-of-chance about competency test. The Service payMe is designed for every interested adult netizen. The service is web-based and a communal crowdfunding scheme. The game is a test of knowledge, interactive quizzing in a multi-choice questions type. payMe™ is designed to play on web browsers enabling desktop and mobile applications. payMe is intentionally created with meritorious rewarding functionality to differ from the original pattern of the gaming industry, which is famously circumscribed by randomly selection of winners in a game of chance that is luck dependent. It is technically structured as an anti-gambling game with superlative uniqueness that distinguished it among competing brands. payMe is an ongoing concern product that will continue to meet users demands that aligns with our believes, principles and goals. The Service's Aim and Objectives The service's core aim is to create economic opportunities using ethical functionalities in a democratized software. Other objectives are: to incentivise intellectual competence. to encourage healthy and fair competition in the field of learning. to promote edifying research habits among scholars using the platform. to provide alternative healthy empowerment platform for gamesters suffering from addiction The Economic Benefit There are so many economic benefits to be derived from the payMe™ product brand. payMe guarantees regular, sustainable fiscal empowerment to users. It is a healthy alternative means of rewarding users’ passion in games. payMe is designed with the ability to enhance valuable learning exercises. Engaging in the contest can help in the reduction of common crimes incidental to youths. The Playing System The console adopts the multiple-choice questions type to create an interactive quizzing format. It offers online learning capabilities that cover extensive information on various academic subjects and soccer (FIFA competitions, leagues, and clubs’ activities). The service features an interactive learning interface and an intuitive time-bound quiz contest amongst participants. The service is deliberately created to differ from the original pattern of the gaming industry, which is luck-dependent, to an intellectual development contest. By this, payMe™ is ethical. Though it entails the use of cash to gain access, however, it guarantees much value for the little Token expended on every entry. payMe™ is designed to play on web browsers enabling desktop and mobile applications. It is playable everywhere with internet access on PC, Laptop, mobile phones, and other devices, if supported. Its technicality and structure make it superlatively unique among competing brands. payMe™ is an ongoing-concerned revolutionary software. The Process payMe™ can be subscribed to online. It entails an initial free membership registration and thereafter funding of a personal wallet with the platform’s native utility asset – the payME Pay Token (payME) Contestants automatically qualify to either make use of the premium entry to the quiz contest or use the payment option. Any of the quiz contests is a set of Ten (10) objective intra-changeable questions. Contestants are expected to provide correct answers to the questions within the swiftest timeframe. Each contestant’s result is displayed after the last question is answered on the contestants’ quiz page and thereafter, updated on the general result page. Weekly participation is limitless for contestants entering as regular quizzers but limited to 10 entries for the premium contestants. Only the best result amongst a Quizzer’s several attempts is registered for the contestant despite when it’s played each week. The first ranked 5% of the weekly contestants based on the most correct answers provided within the swiftest timeframe wins. The Playing Schedule Contests start every Monday at 12 am and end Saturday at 11.59 pm. From 12 am to 11.59 pm every Sunday, results are automatically displayed on the Result Page. The Web Portal Interface and Functions The web/mobile app has interactive interfaces and modules that help Quizzers easily glide through their activities. Some of these modules are described below: a. Wallet: A participant is expected to link his personal blockchain wallet after registration and fund it to enable him gain access to games. Only a decentralized crypto wallet is accepted. b. Quiz: This is 10 revolving questions, each having 4 objectives with 1 possible answer. When entering as a regular quizzer, once the play (ACE or COS) quiz button is clicked, $0.50 worth of payME Token will be debited from the quizzer’s wallet and credited to the platform’s wallet. Next, intra-changeable questions from the Question Bank will be appearing in non sequence routine. Quizzers are expected to provide the correct answers to each of the 10 questions as fast as they could and within 18 seconds. Immediately, after answering the 10th question, the quizzer’s result will display automatically on both the quizzing page and the general result dashboard. c. Tutorial Quiz: As the name implies, this is a free gaming zone created to enable holders of payMe token who may not want to engage in the contest, but want to improve their intellect through quizzing on the platform. However, the user must have payMe token worth $50 USD in his/her personal connected wallet to gain free access at anytime. d. Result Dashboard: this is a general result center for all Contestants. It updates automatically after each game is played during the play period, and according to the most correct answers within the swiftest time frame. That means that if a million quizzers scored 100/100, the system will display their result according to the fastest to answer the entire question using nanoseconds (an SI unit of time equal to one billionth of a second) in computing. So, be rest assured that it is impractical and impossible for 2 Quizzers to tally in the result. This makes payMe unique in the way winners are determined – fastest finger first! Updating of the dashboard however is programmed to freeze once it is 12 am every Sunday to determine the winners by publishing the result of the past week until 12 am on Monday when it continues its routine update. Available Rewards PayMe weekly quiz contest will commence by 12:00AM on Mondays and close by 11:59PM on Saturdays. Results are auto displayed on Sundays. the top most 5% of the participants are declared winners weekly and they are incentivized in ranges of: 1. The topmost 20% of the Winners earn 40% of the total revenue allocation to incentivizing pool in an equal share. 2. While the remaining 80% of the Winners earn 60% of the revenue share on an equal distribution rate. Practically, whatever revenue is generated weekly, 50% is automatically remitted to the incentivizing pool wallet and from there, the topmost 5% of the total participants are rewarded in the following ratio: 40% is equally shared to the topmost 20% while 60% is equally shared to the rest 80% of the winners. Winners claim button would automatically turn green by 12am every Sunday and they can claim their prizes themselves from their dashboard. Every Year, each of the 10 most intelligent Quizzers, drawn from the 52 weeks’ cumulative results of all participants in the ACE Quiz contests are rewarded with a Scholarship Award worth $1000 USDT in payME Token. Criteria is participating in every week of play. Cost of Play Cost of Game $0.50 worth of payME Token per game entry or with a single weekly subscription with payMe token worth $5. NB: The rewards are available for each quizzer's claim from Sunday at 12 am (according to the Nigerian calendar and time).
anujkumarthakur / Rust TutorialIntroduction Note: This edition of the book is the same as The Rust Programming Language available in print and ebook format from No Starch Press. Welcome to The Rust Programming Language, an introductory book about Rust. The Rust programming language helps you write faster, more reliable software. High-level ergonomics and low-level control are often at odds in programming language design; Rust challenges that conflict. Through balancing powerful technical capacity and a great developer experience, Rust gives you the option to control low-level details (such as memory usage) without all the hassle traditionally associated with such control. Who Rust Is For Rust is ideal for many people for a variety of reasons. Let’s look at a few of the most important groups. Teams of Developers Rust is proving to be a productive tool for collaborating among large teams of developers with varying levels of systems programming knowledge. Low-level code is prone to a variety of subtle bugs, which in most other languages can be caught only through extensive testing and careful code review by experienced developers. In Rust, the compiler plays a gatekeeper role by refusing to compile code with these elusive bugs, including concurrency bugs. By working alongside the compiler, the team can spend their time focusing on the program’s logic rather than chasing down bugs. Rust also brings contemporary developer tools to the systems programming world: Cargo, the included dependency manager and build tool, makes adding, compiling, and managing dependencies painless and consistent across the Rust ecosystem. Rustfmt ensures a consistent coding style across developers. The Rust Language Server powers Integrated Development Environment (IDE) integration for code completion and inline error messages. By using these and other tools in the Rust ecosystem, developers can be productive while writing systems-level code. Students Rust is for students and those who are interested in learning about systems concepts. Using Rust, many people have learned about topics like operating systems development. The community is very welcoming and happy to answer student questions. Through efforts such as this book, the Rust teams want to make systems concepts more accessible to more people, especially those new to programming. Companies Hundreds of companies, large and small, use Rust in production for a variety of tasks. Those tasks include command line tools, web services, DevOps tooling, embedded devices, audio and video analysis and transcoding, cryptocurrencies, bioinformatics, search engines, Internet of Things applications, machine learning, and even major parts of the Firefox web browser. Open Source Developers Rust is for people who want to build the Rust programming language, community, developer tools, and libraries. We’d love to have you contribute to the Rust language. People Who Value Speed and Stability Rust is for people who crave speed and stability in a language. By speed, we mean the speed of the programs that you can create with Rust and the speed at which Rust lets you write them. The Rust compiler’s checks ensure stability through feature additions and refactoring. This is in contrast to the brittle legacy code in languages without these checks, which developers are often afraid to modify. By striving for zero-cost abstractions, higher-level features that compile to lower-level code as fast as code written manually, Rust endeavors to make safe code be fast code as well. The Rust language hopes to support many other users as well; those mentioned here are merely some of the biggest stakeholders. Overall, Rust’s greatest ambition is to eliminate the trade-offs that programmers have accepted for decades by providing safety and productivity, speed and ergonomics. Give Rust a try and see if its choices work for you. Who This Book Is For This book assumes that you’ve written code in another programming language but doesn’t make any assumptions about which one. We’ve tried to make the material broadly accessible to those from a wide variety of programming backgrounds. We don’t spend a lot of time talking about what programming is or how to think about it. If you’re entirely new to programming, you would be better served by reading a book that specifically provides an introduction to programming. How to Use This Book In general, this book assumes that you’re reading it in sequence from front to back. Later chapters build on concepts in earlier chapters, and earlier chapters might not delve into details on a topic; we typically revisit the topic in a later chapter. You’ll find two kinds of chapters in this book: concept chapters and project chapters. In concept chapters, you’ll learn about an aspect of Rust. In project chapters, we’ll build small programs together, applying what you’ve learned so far. Chapters 2, 12, and 20 are project chapters; the rest are concept chapters. Chapter 1 explains how to install Rust, how to write a Hello, world! program, and how to use Cargo, Rust’s package manager and build tool. Chapter 2 is a hands-on introduction to the Rust language. Here we cover concepts at a high level, and later chapters will provide additional detail. If you want to get your hands dirty right away, Chapter 2 is the place for that. At first, you might even want to skip Chapter 3, which covers Rust features similar to those of other programming languages, and head straight to Chapter 4 to learn about Rust’s ownership system. However, if you’re a particularly meticulous learner who prefers to learn every detail before moving on to the next, you might want to skip Chapter 2 and go straight to Chapter 3, returning to Chapter 2 when you’d like to work on a project applying the details you’ve learned. Chapter 5 discusses structs and methods, and Chapter 6 covers enums, match expressions, and the if let control flow construct. You’ll use structs and enums to make custom types in Rust. In Chapter 7, you’ll learn about Rust’s module system and about privacy rules for organizing your code and its public Application Programming Interface (API). Chapter 8 discusses some common collection data structures that the standard library provides, such as vectors, strings, and hash maps. Chapter 9 explores Rust’s error-handling philosophy and techniques. Chapter 10 digs into generics, traits, and lifetimes, which give you the power to define code that applies to multiple types. Chapter 11 is all about testing, which even with Rust’s safety guarantees is necessary to ensure your program’s logic is correct. In Chapter 12, we’ll build our own implementation of a subset of functionality from the grep command line tool that searches for text within files. For this, we’ll use many of the concepts we discussed in the previous chapters. Chapter 13 explores closures and iterators: features of Rust that come from functional programming languages. In Chapter 14, we’ll examine Cargo in more depth and talk about best practices for sharing your libraries with others. Chapter 15 discusses smart pointers that the standard library provides and the traits that enable their functionality. In Chapter 16, we’ll walk through different models of concurrent programming and talk about how Rust helps you to program in multiple threads fearlessly. Chapter 17 looks at how Rust idioms compare to object-oriented programming principles you might be familiar with. Chapter 18 is a reference on patterns and pattern matching, which are powerful ways of expressing ideas throughout Rust programs. Chapter 19 contains a smorgasbord of advanced topics of interest, including unsafe Rust, macros, and more about lifetimes, traits, types, functions, and closures. In Chapter 20, we’ll complete a project in which we’ll implement a low-level multithreaded web server! Finally, some appendixes contain useful information about the language in a more reference-like format. Appendix A covers Rust’s keywords, Appendix B covers Rust’s operators and symbols, Appendix C covers derivable traits provided by the standard library, Appendix D covers some useful development tools, and Appendix E explains Rust editions. There is no wrong way to read this book: if you want to skip ahead, go for it! You might have to jump back to earlier chapters if you experience any confusion. But do whatever works for you. An important part of the process of learning Rust is learning how to read the error messages the compiler displays: these will guide you toward working code. As such, we’ll provide many examples that don’t compile along with the error message the compiler will show you in each situation. Know that if you enter and run a random example, it may not compile! Make sure you read the surrounding text to see whether the example you’re trying to run is meant to error. Ferris will also help you distinguish code that isn’t meant to work:
thecre8tor / RuqeRuqe brings the convenient types and methods found in Rust into Dart, such as the Result, Option, pattern-matching, etc.
mojihack / TgTelegram messenger CLI Build Status Command-line interface for Telegram. Uses readline interface. API, Protocol documentation Documentation for Telegram API is available here: http://core.telegram.org/api Documentation for MTproto protocol is available here: http://core.telegram.org/mtproto Upgrading to version 1.0 First of all, the binary is now in ./bin folder and is named telegram-cli. So be careful, not to use old binary. Second, config folder is now ${HOME}/.telegram-cli Third, database is not compatible with older versions, so you'll have to login again. Fourth, in peer_name '#' are substitued to '@'. (Not applied to appending of '#%d' in case of two peers having same name). Installation Clone GitHub Repository git clone --recursive https://github.com/vysheng/tg.git && cd tg Python Support Python support is currently limited to Python 2.7 or Python 3.1+. Other versions may work but are not tested. Linux and BSDs Install libs: readline, openssl and (if you want to use config) libconfig, liblua, python and libjansson. If you do not want to use them pass options --disable-libconfig, --disable-liblua, --disable-python and --disable-json respectively. On Ubuntu/Debian use: sudo apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev libjansson-dev libpython-dev make On gentoo: sudo emerge -av sys-libs/readline dev-libs/libconfig dev-libs/openssl dev-lang/lua dev-libs/libevent dev-libs/jansson dev-lang/python On Fedora: sudo dnf install lua-devel openssl-devel libconfig-devel readline-devel libevent-devel libjansson-devel python-devel On Archlinux: yaourt -S telegram-cli-git On FreeBSD: pkg install libconfig libexecinfo lua52 python On OpenBSD: pkg_add libconfig libexecinfo lua python On openSUSE: sudo zypper in lua-devel libconfig-devel readline-devel libevent-devel libjansson-devel python-devel libopenssl-devel Then, ./configure make Other methods to install on linux On Gentoo: use ebuild provided. On Arch: https://aur.archlinux.org/packages/telegram-cli-git Mac OS X The client depends on readline library and libconfig, which are not included in OS X by default. You have to install these libraries manually. If using Homebrew: brew install libconfig readline lua python libevent jansson export CFLAGS="-I/usr/local/include -I/usr/local/Cellar/readline/6.3.8/include" export LDFLAGS="-L/usr/local/lib -L/usr/local/Cellar/readline/6.3.8/lib" ./configure && make Thanks to @jfontan for this solution. If using MacPorts: sudo port install libconfig-hr sudo port install readline sudo port install lua51 sudo port install python34 sudo port install libevent export CFLAGS="-I/usr/local/include -I/opt/local/include -I/opt/local/include/lua-5.1" export LDFLAGS="-L/usr/local/lib -L/opt/local/lib -L/opt/local/lib/lua-5.1" ./configure && make Install these ports: devel/libconfig devel/libexecinfo lang/lua52 Then build: env CC=clang CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib LUA=/usr/local/bin/lua52 LUA_INCLUDE=-I/usr/local/include/lua52 LUA_LIB=-llua-5.2 ./configure make Other UNIX If you manage to launch it on other UNIX, please let me know. Contacts If you would like to ask a question, you can write to my telegram or to the github (or both). To contact me via telegram, you should use import_card method with argument 000653bf:0738ca5d:5521fbac:29246815:a27d0cda Usage bin/telegram-cli -k <public-server-key> By default, the public key is stored in tg-server.pub in the same folder or in /etc/telegram-cli/server.pub. If not, specify where to find it: bin/telegram-cli -k tg-server.pub Client support TAB completion and command history. Peer refers to the name of the contact or dialog and can be accessed by TAB completion. For user contacts peer name is Name Lastname with all spaces changed to underscores. For chats it is it's title with all spaces changed to underscores For encrypted chats it is <Exсlamation mark> Name Lastname with all spaces changed to underscores. If two or more peers have same name, number is appended to the name. (for example A_B, A_B#1, A_B#2 and so on) Supported commands Messaging msg <peer> Text - sends message to this peer fwd <user> <msg-seqno> - forward message to user. You can see message numbers starting client with -N chat_with_peer <peer> starts one on one chat session with this peer. /exit or /quit to end this mode. add_contact <phone-number> <first-name> <last-name> - tries to add contact to contact-list by phone rename_contact <user> <first-name> <last-name> - tries to rename contact. If you have another device it will be a fight mark_read <peer> - mark read all received messages with peer delete_msg <msg-seqno> - deletes message (not completly, though) restore_msg <msg-seqno> - restores delete message. Impossible for secret chats. Only possible short time (one hour, I think) after deletion Multimedia send_photo <peer> <photo-file-name> - sends photo to peer send_video <peer> <video-file-name> - sends video to peer send_text <peer> <text-file-name> - sends text file as plain messages load_photo/load_video/load_video_thumb/load_audio/load_document/load_document_thumb <msg-seqno> - loads photo/video/audio/document to download dir view_photo/view_video/view_video_thumb/view_audio/view_document/view_document_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer fwd_media <msg-seqno> send media in your message. Use this to prevent sharing info about author of media (though, it is possible to determine user_id from media itself, it is not possible get access_hash of this user) set_profile_photo <photo-file-name> - sets userpic. Photo should be square, or server will cut biggest central square part Group chat options chat_info <chat> - prints info about chat chat_add_user <chat> <user> - add user to chat chat_del_user <chat> <user> - remove user from chat rename_chat <chat> <new-name> create_group_chat <chat topic> <user1> <user2> <user3> ... - creates a groupchat with users, use chat_add_user to add more users chat_set_photo <chat> <photo-file-name> - sets group chat photo. Same limits as for profile photos. Search search <peer> pattern - searches pattern in messages with peer global_search pattern - searches pattern in all messages Secret chat create_secret_chat <user> - creates secret chat with this user visualize_key <secret_chat> - prints visualization of encryption key. You should compare it to your partner's one set_ttl <secret_chat> <ttl> - sets ttl to secret chat. Though client does ignore it, client on other end can make use of it accept_secret_chat <secret_chat> - manually accept secret chat (only useful when starting with -E key) Stats and various info user_info <user> - prints info about user history <peer> [limit] - prints history (and marks it as read). Default limit = 40 dialog_list - prints info about your dialogs contact_list - prints info about users in your contact list suggested_contacts - print info about contacts, you have max common friends stats - just for debugging show_license - prints contents of GPLv2 help - prints this help get_self - get our user info Card export_card - print your 'card' that anyone can later use to import your contact import_card <card> - gets user by card. You can write messages to him after that. Other quit - quit safe_quit - wait for all queries to end then quit
iammukeshm / Options Pattern Aspnet CoreHow do you load & validate your Configurations in ASP.NET Core applications from appsettings.json? 🤔
gptankit / MlcacheMulti-level cache with options for read/write patterns
trustdan / IBKR TraderAn automated trading system that implements vertical spread trading strategies using Interactive Brokers (IBKR) API. The system scans for specific technical patterns, selects optimal option spreads, and handles trade execution for equity options. Built with Python and Go.
janestreet / Ppx OptionalPattern matching on flat options
questionmark1122 / Cnn10#!bash # # bash completion support for core Git. # # Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org> # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). # Distributed under the GNU General Public License, version 2.0. # # The contained completion routines provide support for completing: # # *) local and remote branch names # *) local and remote tag names # *) .git/remotes file names # *) git 'subcommands' # *) tree paths within 'ref:path/to/file' expressions # *) common --long-options # # To use these routines: # # 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). # 2) Added the following line to your .bashrc: # source ~/.git-completion.sh # # 3) Consider changing your PS1 to also show the current branch: # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' # # The argument to __git_ps1 will be displayed only if you # are currently in a git repository. The %s token will be # the name of the current branch. # # In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty # value, unstaged (*) and staged (+) changes will be shown next # to the branch name. You can configure this per-repository # with the bash.showDirtyState variable, which defaults to true # once GIT_PS1_SHOWDIRTYSTATE is enabled. # # You can also see if currently something is stashed, by setting # GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, # then a '$' will be shown next to the branch name. # # If you would like to see if there're untracked files, then you can # set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're # untracked files, then a '%' will be shown next to the branch name. # # If you would like to see the difference between HEAD and its # upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates # you are behind, ">" indicates you are ahead, and "<>" # indicates you have diverged. You can further control # behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated # list of values: # verbose show number of commits ahead/behind (+/-) upstream # legacy don't use the '--count' option available in recent # versions of git-rev-list # git always compare HEAD to @{upstream} # svn always compare HEAD to your SVN upstream # By default, __git_ps1 will compare HEAD to your SVN upstream # if it can find one, or @{upstream} otherwise. Once you have # set GIT_PS1_SHOWUPSTREAM, you can override it on a # per-repository basis by setting the bash.showUpstream config # variable. # # # To submit patches: # # *) Read Documentation/SubmittingPatches # *) Send all patches to the current maintainer: # # "Shawn O. Pearce" <spearce@spearce.org> # # *) Always CC the Git mailing list: # # git@vger.kernel.org # case "$COMP_WORDBREAKS" in *:*) : great ;; *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" esac # __gitdir accepts 0 or 1 arguments (i.e., location) # returns location of .git repo __gitdir () { if [ -z "${1-}" ]; then if [ -n "${__git_dir-}" ]; then echo "$__git_dir" elif [ -d .git ]; then echo .git else git rev-parse --git-dir 2>/dev/null fi elif [ -d "$1/.git" ]; then echo "$1/.git" else echo "$1" fi } # stores the divergence from upstream in $p # used by GIT_PS1_SHOWUPSTREAM __git_ps1_show_upstream () { local key value local svn_remote=() svn_url_pattern count n local upstream=git legacy="" verbose="" # get some config options from git-config while read key value; do case "$key" in bash.showupstream) GIT_PS1_SHOWUPSTREAM="$value" if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then p="" return fi ;; svn-remote.*.url) svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" svn_url_pattern+="\\|$value" upstream=svn+git # default upstream is SVN if available, else git ;; esac done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ') # parse configuration values for option in ${GIT_PS1_SHOWUPSTREAM}; do case "$option" in git|svn) upstream="$option" ;; verbose) verbose=1 ;; legacy) legacy=1 ;; esac done # Find our upstream case "$upstream" in git) upstream="@{upstream}" ;; svn*) # get the upstream from the "git-svn-id: ..." in a commit message # (git-svn uses essentially the same procedure internally) local svn_upstream=($(git log --first-parent -1 \ --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null)) if [[ 0 -ne ${#svn_upstream[@]} ]]; then svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} svn_upstream=${svn_upstream%@*} for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do svn_upstream=${svn_upstream#${svn_remote[$n]}} done if [[ -z "$svn_upstream" ]]; then # default branch name for checkouts with no layout: upstream=${GIT_SVN_ID:-git-svn} else upstream=${svn_upstream#/} fi elif [[ "svn+git" = "$upstream" ]]; then upstream="@{upstream}" fi ;; esac # Find how many commits we are ahead/behind our upstream if [[ -z "$legacy" ]]; then count="$(git rev-list --count --left-right \ "$upstream"...HEAD 2>/dev/null)" else # produce equivalent output to --count for older versions of git local commits if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" then local commit behind=0 ahead=0 for commit in $commits do case "$commit" in "<"*) let ++behind ;; *) let ++ahead ;; esac done count="$behind $ahead" else count="" fi fi # calculate the result if [[ -z "$verbose" ]]; then case "$count" in "") # no upstream p="" ;; "0 0") # equal to upstream p="=" ;; "0 "*) # ahead of upstream p=">" ;; *" 0") # behind upstream p="<" ;; *) # diverged from upstream p="<>" ;; esac else case "$count" in "") # no upstream p="" ;; "0 0") # equal to upstream p=" u=" ;; "0 "*) # ahead of upstream p=" u+${count#0 }" ;; *" 0") # behind upstream p=" u-${count% 0}" ;; *) # diverged from upstream p=" u+${count#* }-${count% *}" ;; esac fi } # __git_ps1 accepts 0 or 1 arguments (i.e., format string) # returns text to add to bash PS1 prompt (includes branch name) __git_ps1 () { local g="$(__gitdir)" if [ -n "$g" ]; then local r="" local b="" if [ -f "$g/rebase-merge/interactive" ]; then r="|REBASE-i" b="$(cat "$g/rebase-merge/head-name")" elif [ -d "$g/rebase-merge" ]; then r="|REBASE-m" b="$(cat "$g/rebase-merge/head-name")" else if [ -d "$g/rebase-apply" ]; then if [ -f "$g/rebase-apply/rebasing" ]; then r="|REBASE" elif [ -f "$g/rebase-apply/applying" ]; then r="|AM" else r="|AM/REBASE" fi elif [ -f "$g/MERGE_HEAD" ]; then r="|MERGING" elif [ -f "$g/BISECT_LOG" ]; then r="|BISECTING" fi b="$(git symbolic-ref HEAD 2>/dev/null)" || { b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains) git describe --contains HEAD ;; (branch) git describe --contains --all HEAD ;; (describe) git describe HEAD ;; (* | default) git describe --exact-match HEAD ;; esac 2>/dev/null)" || b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || b="unknown" b="($b)" } fi local w="" local i="" local s="" local u="" local c="" local p="" if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then c="BARE:" else b="GIT_DIR!" fi elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then git diff --no-ext-diff --quiet --exit-code || w="*" if git rev-parse --quiet --verify HEAD >/dev/null; then git diff-index --cached --quiet HEAD -- || i="+" else i="#" fi fi fi if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" fi if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then if [ -n "$(git ls-files --others --exclude-standard)" ]; then u="%" fi fi if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then __git_ps1_show_upstream fi fi local f="$w$i$s$u" printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" fi } # __gitcomp_1 requires 2 arguments __gitcomp_1 () { local c IFS=' '$'\t'$'\n' for c in $1; do case "$c$2" in --*=*) printf %s$'\n' "$c$2" ;; *.) printf %s$'\n' "$c$2" ;; *) printf %s$'\n' "$c$2 " ;; esac done } # __gitcomp accepts 1, 2, 3, or 4 arguments # generates completion reply with compgen __gitcomp () { local cur="${COMP_WORDS[COMP_CWORD]}" if [ $# -gt 2 ]; then cur="$3" fi case "$cur" in --*=) COMPREPLY=() ;; *) local IFS=$'\n' COMPREPLY=($(compgen -P "${2-}" \ -W "$(__gitcomp_1 "${1-}" "${4-}")" \ -- "$cur")) ;; esac } # __git_heads accepts 0 or 1 arguments (to pass to __gitdir) __git_heads () { local cmd i is_hash=y dir="$(__gitdir "${1-}")" if [ -d "$dir" ]; then git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ refs/heads return fi for i in $(git ls-remote "${1-}" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; n,*) is_hash=y; echo "$i" ;; esac done } # __git_tags accepts 0 or 1 arguments (to pass to __gitdir) __git_tags () { local cmd i is_hash=y dir="$(__gitdir "${1-}")" if [ -d "$dir" ]; then git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ refs/tags return fi for i in $(git ls-remote "${1-}" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; n,*) is_hash=y; echo "$i" ;; esac done } # __git_refs accepts 0 or 1 arguments (to pass to __gitdir) __git_refs () { local i is_hash=y dir="$(__gitdir "${1-}")" local cur="${COMP_WORDS[COMP_CWORD]}" format refs if [ -d "$dir" ]; then case "$cur" in refs|refs/*) format="refname" refs="${cur%/*}" ;; *) for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do if [ -e "$dir/$i" ]; then echo $i; fi done format="refname:short" refs="refs/tags refs/heads refs/remotes" ;; esac git --git-dir="$dir" for-each-ref --format="%($format)" \ $refs return fi for i in $(git ls-remote "$dir" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;; n,*) is_hash=y; echo "$i" ;; esac done } # __git_refs2 requires 1 argument (to pass to __git_refs) __git_refs2 () { local i for i in $(__git_refs "$1"); do echo "$i:$i" done } # __git_refs_remotes requires 1 argument (to pass to ls-remote) __git_refs_remotes () { local cmd i is_hash=y for i in $(git ls-remote "$1" 2>/dev/null); do case "$is_hash,$i" in n,refs/heads/*) is_hash=y echo "$i:refs/remotes/$1/${i#refs/heads/}" ;; y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y;; n,*) is_hash=y; ;; esac done } __git_remotes () { local i ngoff IFS=$'\n' d="$(__gitdir)" shopt -q nullglob || ngoff=1 shopt -s nullglob for i in "$d/remotes"/*; do echo ${i#$d/remotes/} done [ "$ngoff" ] && shopt -u nullglob for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do i="${i#remote.}" echo "${i/.url*/}" done } __git_list_merge_strategies () { git merge -s help 2>&1 | sed -n -e '/[Aa]vailable strategies are: /,/^$/{ s/\.$// s/.*:// s/^[ ]*// s/[ ]*$// p }' } __git_merge_strategies= # 'git merge -s help' (and thus detection of the merge strategy # list) fails, unfortunately, if run outside of any git working # tree. __git_merge_strategies is set to the empty string in # that case, and the detection will be repeated the next time it # is needed. __git_compute_merge_strategies () { : ${__git_merge_strategies:=$(__git_list_merge_strategies)} } __git_complete_file () { local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in ?*:*) ref="${cur%%:*}" cur="${cur#*:}" case "$cur" in ?*/*) pfx="${cur%/*}" cur="${cur##*/}" ls="$ref:$pfx" pfx="$pfx/" ;; *) ls="$ref" ;; esac case "$COMP_WORDBREAKS" in *:*) : great ;; *) pfx="$ref:$pfx" ;; esac local IFS=$'\n' COMPREPLY=($(compgen -P "$pfx" \ -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \ | sed '/^100... blob /{ s,^.* ,, s,$, , } /^120000 blob /{ s,^.* ,, s,$, , } /^040000 tree /{ s,^.* ,, s,$,/, } s/^.* //')" \ -- "$cur")) ;; *) __gitcomp "$(__git_refs)" ;; esac } __git_complete_revlist () { local pfx cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in *...*) pfx="${cur%...*}..." cur="${cur#*...}" __gitcomp "$(__git_refs)" "$pfx" "$cur" ;; *..*) pfx="${cur%..*}.." cur="${cur#*..}" __gitcomp "$(__git_refs)" "$pfx" "$cur" ;; *) __gitcomp "$(__git_refs)" ;; esac } __git_complete_remote_or_refspec () { local cmd="${COMP_WORDS[1]}" local cur="${COMP_WORDS[COMP_CWORD]}" local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0 while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;; --all) case "$cmd" in push) no_complete_refspec=1 ;; fetch) COMPREPLY=() return ;; *) ;; esac ;; -*) ;; *) remote="$i"; break ;; esac c=$((++c)) done if [ -z "$remote" ]; then __gitcomp "$(__git_remotes)" return fi if [ $no_complete_refspec = 1 ]; then COMPREPLY=() return fi [ "$remote" = "." ] && remote= case "$cur" in *:*) case "$COMP_WORDBREAKS" in *:*) : great ;; *) pfx="${cur%%:*}:" ;; esac cur="${cur#*:}" lhs=0 ;; +*) pfx="+" cur="${cur#+}" ;; esac case "$cmd" in fetch) if [ $lhs = 1 ]; then __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur" else __gitcomp "$(__git_refs)" "$pfx" "$cur" fi ;; pull) if [ $lhs = 1 ]; then __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur" else __gitcomp "$(__git_refs)" "$pfx" "$cur" fi ;; push) if [ $lhs = 1 ]; then __gitcomp "$(__git_refs)" "$pfx" "$cur" else __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur" fi ;; esac } __git_complete_strategy () { __git_compute_merge_strategies case "${COMP_WORDS[COMP_CWORD-1]}" in -s|--strategy) __gitcomp "$__git_merge_strategies" return 0 esac local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --strategy=*) __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}" return 0 ;; esac return 1 } __git_list_all_commands () { local i IFS=" "$'\n' for i in $(git help -a|egrep '^ [a-zA-Z0-9]') do case $i in *--*) : helper pattern;; *) echo $i;; esac done } __git_all_commands= __git_compute_all_commands () { : ${__git_all_commands:=$(__git_list_all_commands)} } __git_list_porcelain_commands () { local i IFS=" "$'\n' __git_compute_all_commands for i in "help" $__git_all_commands do case $i in *--*) : helper pattern;; applymbox) : ask gittus;; applypatch) : ask gittus;; archimport) : import;; cat-file) : plumbing;; check-attr) : plumbing;; check-ref-format) : plumbing;; checkout-index) : plumbing;; commit-tree) : plumbing;; count-objects) : infrequent;; cvsexportcommit) : export;; cvsimport) : import;; cvsserver) : daemon;; daemon) : daemon;; diff-files) : plumbing;; diff-index) : plumbing;; diff-tree) : plumbing;; fast-import) : import;; fast-export) : export;; fsck-objects) : plumbing;; fetch-pack) : plumbing;; fmt-merge-msg) : plumbing;; for-each-ref) : plumbing;; hash-object) : plumbing;; http-*) : transport;; index-pack) : plumbing;; init-db) : deprecated;; local-fetch) : plumbing;; lost-found) : infrequent;; ls-files) : plumbing;; ls-remote) : plumbing;; ls-tree) : plumbing;; mailinfo) : plumbing;; mailsplit) : plumbing;; merge-*) : plumbing;; mktree) : plumbing;; mktag) : plumbing;; pack-objects) : plumbing;; pack-redundant) : plumbing;; pack-refs) : plumbing;; parse-remote) : plumbing;; patch-id) : plumbing;; peek-remote) : plumbing;; prune) : plumbing;; prune-packed) : plumbing;; quiltimport) : import;; read-tree) : plumbing;; receive-pack) : plumbing;; reflog) : plumbing;; remote-*) : transport;; repo-config) : deprecated;; rerere) : plumbing;; rev-list) : plumbing;; rev-parse) : plumbing;; runstatus) : plumbing;; sh-setup) : internal;; shell) : daemon;; show-ref) : plumbing;; send-pack) : plumbing;; show-index) : plumbing;; ssh-*) : transport;; stripspace) : plumbing;; symbolic-ref) : plumbing;; tar-tree) : deprecated;; unpack-file) : plumbing;; unpack-objects) : plumbing;; update-index) : plumbing;; update-ref) : plumbing;; update-server-info) : daemon;; upload-archive) : plumbing;; upload-pack) : plumbing;; write-tree) : plumbing;; var) : infrequent;; verify-pack) : infrequent;; verify-tag) : plumbing;; *) echo $i;; esac done } __git_porcelain_commands= __git_compute_porcelain_commands () { __git_compute_all_commands : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)} } __git_aliases () { local i IFS=$'\n' for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do case "$i" in alias.*) i="${i#alias.}" echo "${i/ */}" ;; esac done } # __git_aliased_command requires 1 argument __git_aliased_command () { local word cmdline=$(git --git-dir="$(__gitdir)" \ config --get "alias.$1") for word in $cmdline; do case "$word" in \!gitk|gitk) echo "gitk" return ;; \!*) : shell command alias ;; -*) : option ;; *=*) : setting env ;; git) : git itself ;; *) echo "$word" return esac done } # __git_find_on_cmdline requires 1 argument __git_find_on_cmdline () { local word subcommand c=1 while [ $c -lt $COMP_CWORD ]; do word="${COMP_WORDS[c]}" for subcommand in $1; do if [ "$subcommand" = "$word" ]; then echo "$subcommand" return fi done c=$((++c)) done } __git_has_doubledash () { local c=1 while [ $c -lt $COMP_CWORD ]; do if [ "--" = "${COMP_WORDS[c]}" ]; then return 0 fi c=$((++c)) done return 1 } __git_whitespacelist="nowarn warn error error-all fix" _git_am () { local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" if [ -d "$dir"/rebase-apply ]; then __gitcomp "--skip --continue --resolved --abort" return fi case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; --*) __gitcomp " --3way --committer-date-is-author-date --ignore-date --ignore-whitespace --ignore-space-change --interactive --keep --no-utf8 --signoff --utf8 --whitespace= --scissors " return esac COMPREPLY=() } _git_apply () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; --*) __gitcomp " --stat --numstat --summary --check --index --cached --index-info --reverse --reject --unidiff-zero --apply --no-add --exclude= --ignore-whitespace --ignore-space-change --whitespace= --inaccurate-eof --verbose " return esac COMPREPLY=() } _git_add () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --interactive --refresh --patch --update --dry-run --ignore-errors --intent-to-add " return esac COMPREPLY=() } _git_archive () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --format=*) __gitcomp "$(git archive --list)" "" "${cur##--format=}" return ;; --remote=*) __gitcomp "$(__git_remotes)" "" "${cur##--remote=}" return ;; --*) __gitcomp " --format= --list --verbose --prefix= --remote= --exec= " return ;; esac __git_complete_file } _git_bisect () { __git_has_doubledash && return local subcommands="start bad good skip reset visualize replay log run" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" return fi case "$subcommand" in bad|good|reset|skip) __gitcomp "$(__git_refs)" ;; *) COMPREPLY=() ;; esac } _git_branch () { local i c=1 only_local_ref="n" has_r="n" while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in -d|-m) only_local_ref="y" ;; -r) has_r="y" ;; esac c=$((++c)) done case "${COMP_WORDS[COMP_CWORD]}" in --*) __gitcomp " --color --no-color --verbose --abbrev= --no-abbrev --track --no-track --contains --merged --no-merged --set-upstream " ;; *) if [ $only_local_ref = "y" -a $has_r = "n" ]; then __gitcomp "$(__git_heads)" else __gitcomp "$(__git_refs)" fi ;; esac } _git_bundle () { local cmd="${COMP_WORDS[2]}" case "$COMP_CWORD" in 2) __gitcomp "create list-heads verify unbundle" ;; 3) # looking for a file ;; *) case "$cmd" in create) __git_complete_revlist ;; esac ;; esac } _git_checkout () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --conflict=*) __gitcomp "diff3 merge" "" "${cur##--conflict=}" ;; --*) __gitcomp " --quiet --ours --theirs --track --no-track --merge --conflict= --orphan --patch " ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_cherry () { __gitcomp "$(__git_refs)" } _git_cherry_pick () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--edit --no-commit" ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_clean () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--dry-run --quiet" return ;; esac COMPREPLY=() } _git_clone () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --local --no-hardlinks --shared --reference --quiet --no-checkout --bare --mirror --origin --upload-pack --template= --depth " return ;; esac COMPREPLY=() } _git_commit () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --cleanup=*) __gitcomp "default strip verbatim whitespace " "" "${cur##--cleanup=}" return ;; --reuse-message=*) __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}" return ;; --reedit-message=*) __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}" return ;; --untracked-files=*) __gitcomp "all no normal" "" "${cur##--untracked-files=}" return ;; --*) __gitcomp " --all --author= --signoff --verify --no-verify --edit --amend --include --only --interactive --dry-run --reuse-message= --reedit-message= --reset-author --file= --message= --template= --cleanup= --untracked-files --untracked-files= --verbose --quiet " return esac COMPREPLY=() } _git_describe () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --all --tags --contains --abbrev= --candidates= --exact-match --debug --long --match --always " return esac __gitcomp "$(__git_refs)" } __git_diff_common_options="--stat --numstat --shortstat --summary --patch-with-stat --name-only --name-status --color --no-color --color-words --no-renames --check --full-index --binary --abbrev --diff-filter= --find-copies-harder --text --ignore-space-at-eol --ignore-space-change --ignore-all-space --exit-code --quiet --ext-diff --no-ext-diff --no-prefix --src-prefix= --dst-prefix= --inter-hunk-context= --patience --raw --dirstat --dirstat= --dirstat-by-file --dirstat-by-file= --cumulative " _git_diff () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex --base --ours --theirs $__git_diff_common_options " return ;; esac __git_complete_file } __git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff tkdiff vimdiff gvimdiff xxdiff araxis p4merge " _git_difftool () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --tool=*) __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}" return ;; --*) __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex --base --ours --theirs --no-renames --diff-filter= --find-copies-harder --relative --ignore-submodules --tool=" return ;; esac __git_complete_file } __git_fetch_options=" --quiet --verbose --append --upload-pack --force --keep --depth= --tags --no-tags --all --prune --dry-run " _git_fetch () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "$__git_fetch_options" return ;; esac __git_complete_remote_or_refspec } _git_format_patch () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --thread=*) __gitcomp " deep shallow " "" "${cur##--thread=}" return ;; --*) __gitcomp " --stdout --attach --no-attach --thread --thread= --output-directory --numbered --start-number --numbered-files --keep-subject --signoff --signature --no-signature --in-reply-to= --cc= --full-index --binary --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= --inline --suffix= --ignore-if-in-upstream --subject-prefix= " return ;; esac __git_complete_revlist } _git_fsck () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --tags --root --unreachable --cache --no-reflogs --full --strict --verbose --lost-found " return ;; esac COMPREPLY=() } _git_gc () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--prune --aggressive" return ;; esac COMPREPLY=() } _git_gitk () { _gitk } _git_grep () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --cached --text --ignore-case --word-regexp --invert-match --full-name --extended-regexp --basic-regexp --fixed-strings --files-with-matches --name-only --files-without-match --max-depth --count --and --or --not --all-match " return ;; esac __gitcomp "$(__git_refs)" } _git_help () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--all --info --man --web" return ;; esac __git_compute_all_commands __gitcomp "$__git_all_commands attributes cli core-tutorial cvs-migration diffcore gitk glossary hooks ignore modules repository-layout tutorial tutorial-2 workflows " } _git_init () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --shared=*) __gitcomp " false true umask group all world everybody " "" "${cur##--shared=}" return ;; --*) __gitcomp "--quiet --bare --template= --shared --shared=" return ;; esac COMPREPLY=() } _git_ls_files () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--cached --deleted --modified --others --ignored --stage --directory --no-empty-directory --unmerged --killed --exclude= --exclude-from= --exclude-per-directory= --exclude-standard --error-unmatch --with-tree= --full-name --abbrev --ignored --exclude-per-directory " return ;; esac COMPREPLY=() } _git_ls_remote () { __gitcomp "$(__git_remotes)" } _git_ls_tree () { __git_complete_file } # Options that go well for log, shortlog and gitk __git_log_common_options=" --not --all --branches --tags --remotes --first-parent --merges --no-merges --max-count= --max-age= --since= --after= --min-age= --until= --before= " # Options that go well for log and gitk (not shortlog) __git_log_gitk_options=" --dense --sparse --full-history --simplify-merges --simplify-by-decoration --left-right " # Options that go well for log and shortlog (not gitk) __git_log_shortlog_options=" --author= --committer= --grep= --all-match " __git_log_pretty_formats="oneline short medium full fuller email raw format:" __git_log_date_formats="relative iso8601 rfc2822 short local default raw" _git_log () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" local g="$(git rev-parse --git-dir 2>/dev/null)" local merge="" if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi case "$cur" in --pretty=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--pretty=}" return ;; --format=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--format=}" return ;; --date=*) __gitcomp "$__git_log_date_formats" "" "${cur##--date=}" return ;; --decorate=*) __gitcomp "long short" "" "${cur##--decorate=}" return ;; --*) __gitcomp " $__git_log_common_options $__git_log_shortlog_options $__git_log_gitk_options --root --topo-order --date-order --reverse --follow --full-diff --abbrev-commit --abbrev= --relative-date --date= --pretty= --format= --oneline --cherry-pick --graph --decorate --decorate= --walk-reflogs --parents --children $merge $__git_diff_common_options --pickaxe-all --pickaxe-regex " return ;; esac __git_complete_revlist } __git_merge_options=" --no-commit --no-stat --log --no-log --squash --strategy --commit --stat --no-squash --ff --no-ff --ff-only " _git_merge () { __git_complete_strategy && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "$__git_merge_options" return esac __gitcomp "$(__git_refs)" } _git_mergetool () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --tool=*) __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}" return ;; --*) __gitcomp "--tool=" return ;; esac COMPREPLY=() } _git_merge_base () { __gitcomp "$(__git_refs)" } _git_mv () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--dry-run" return ;; esac COMPREPLY=() } _git_name_rev () { __gitcomp "--tags --all --stdin" } _git_notes () { local subcommands="edit show" if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then __gitcomp "$subcommands" return fi case "${COMP_WORDS[COMP_CWORD-1]}" in -m|-F) COMPREPLY=() ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_pull () { __git_complete_strategy && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --rebase --no-rebase $__git_merge_options $__git_fetch_options " return ;; esac __git_complete_remote_or_refspec } _git_push () { local cur="${COMP_WORDS[COMP_CWORD]}" case "${COMP_WORDS[COMP_CWORD-1]}" in --repo) __gitcomp "$(__git_remotes)" return esac case "$cur" in --repo=*) __gitcomp "$(__git_remotes)" "" "${cur##--repo=}" return ;; --*) __gitcomp " --all --mirror --tags --dry-run --force --verbose --receive-pack= --repo= " return ;; esac __git_complete_remote_or_refspec } _git_rebase () { local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then __gitcomp "--continue --skip --abort" return fi __git_complete_strategy && return case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; --*) __gitcomp " --onto --merge --strategy --interactive --preserve-merges --stat --no-stat --committer-date-is-author-date --ignore-date --ignore-whitespace --whitespace= --autosquash " return esac __gitcomp "$(__git_refs)" } __git_send_email_confirm_options="always never auto cc compose" __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all" _git_send_email () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --confirm=*) __gitcomp " $__git_send_email_confirm_options " "" "${cur##--confirm=}" return ;; --suppress-cc=*) __gitcomp " $__git_send_email_suppresscc_options " "" "${cur##--suppress-cc=}" return ;; --smtp-encryption=*) __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}" return ;; --*) __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to --compose --confirm= --dry-run --envelope-sender --from --identity --in-reply-to --no-chain-reply-to --no-signed-off-by-cc --no-suppress-from --no-thread --quiet --signed-off-by-cc --smtp-pass --smtp-server --smtp-server-port --smtp-encryption= --smtp-user --subject --suppress-cc= --suppress-from --thread --to --validate --no-validate" return ;; esac COMPREPLY=() } _git_stage () { _git_add } __git_config_get_set_variables () { local prevword word config_file= c=$COMP_CWORD while [ $c -gt 1 ]; do word="${COMP_WORDS[c]}" case "$word" in --global|--system|--file=*) config_file="$word" break ;; -f|--file) config_file="$word $prevword" break ;; esac prevword=$word c=$((--c)) done git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null | while read line do case "$line" in *.*=*) echo "${line/=*/}" ;; esac done } _git_config () { local cur="${COMP_WORDS[COMP_CWORD]}" local prv="${COMP_WORDS[COMP_CWORD-1]}" case "$prv" in branch.*.remote) __gitcomp "$(__git_remotes)" return ;; branch.*.merge) __gitcomp "$(__git_refs)" return ;; remote.*.fetch) local remote="${prv#remote.}" remote="${remote%.fetch}" __gitcomp "$(__git_refs_remotes "$remote")" return ;; remote.*.push) local remote="${prv#remote.}" remote="${remote%.push}" __gitcomp "$(git --git-dir="$(__gitdir)" \ for-each-ref --format='%(refname):%(refname)' \ refs/heads)" return ;; pull.twohead|pull.octopus) __git_compute_merge_strategies __gitcomp "$__git_merge_strategies" return ;; color.branch|color.diff|color.interactive|\ color.showbranch|color.status|color.ui) __gitcomp "always never auto" return ;; color.pager) __gitcomp "false true" return ;; color.*.*) __gitcomp " normal black red green yellow blue magenta cyan white bold dim ul blink reverse " return ;; help.format) __gitcomp "man info web html" return ;; log.date) __gitcomp "$__git_log_date_formats" return ;; sendemail.aliasesfiletype) __gitcomp "mutt mailrc pine elm gnus" return ;; sendemail.confirm) __gitcomp "$__git_send_email_confirm_options" return ;; sendemail.suppresscc) __gitcomp "$__git_send_email_suppresscc_options" return ;; --get|--get-all|--unset|--unset-all) __gitcomp "$(__git_config_get_set_variables)" return ;; *.*) COMPREPLY=() return ;; esac case "$cur" in --*) __gitcomp " --global --system --file= --list --replace-all --get --get-all --get-regexp --add --unset --unset-all --remove-section --rename-section " return ;; branch.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur" return ;; branch.*) local pfx="${cur%.*}." cur="${cur#*.}" __gitcomp "$(__git_heads)" "$pfx" "$cur" "." return ;; guitool.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp " argprompt cmd confirm needsfile noconsole norescan prompt revprompt revunmerged title " "$pfx" "$cur" return ;; difftool.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "cmd path" "$pfx" "$cur" return ;; man.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "cmd path" "$pfx" "$cur" return ;; mergetool.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "cmd path trustExitCode" "$pfx" "$cur" return ;; pager.*) local pfx="${cur%.*}." cur="${cur#*.}" __git_compute_all_commands __gitcomp "$__git_all_commands" "$pfx" "$cur" return ;; remote.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp " url proxy fetch push mirror skipDefaultUpdate receivepack uploadpack tagopt pushurl " "$pfx" "$cur" return ;; remote.*) local pfx="${cur%.*}." cur="${cur#*.}" __gitcomp "$(__git_remotes)" "$pfx" "$cur" "." return ;; url.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur" return ;; esac __gitcomp " add.ignore-errors alias. apply.ignorewhitespace apply.whitespace branch.autosetupmerge branch.autosetuprebase clean.requireForce color.branch color.branch.current color.branch.local color.branch.plain color.branch.remote color.diff color.diff.commit color.diff.frag color.diff.meta color.diff.new color.diff.old color.diff.plain color.diff.whitespace color.grep color.grep.external color.grep.match color.interactive color.interactive.header color.interactive.help color.interactive.prompt color.pager color.showbranch color.status color.status.added color.status.changed color.status.header color.status.nobranch color.status.untracked color.status.updated color.ui commit.template core.autocrlf core.bare core.compression core.createObject core.deltaBaseCacheLimit core.editor core.excludesfile core.fileMode core.fsyncobjectfiles core.gitProxy core.ignoreCygwinFSTricks core.ignoreStat core.logAllRefUpdates core.loosecompression core.packedGitLimit core.packedGitWindowSize core.pager core.preferSymlinkRefs core.preloadindex core.quotepath core.repositoryFormatVersion core.safecrlf core.sharedRepository core.symlinks core.trustctime core.warnAmbiguousRefs core.whitespace core.worktree diff.autorefreshindex diff.external diff.mnemonicprefix diff.renameLimit diff.renameLimit. diff.renames diff.suppressBlankEmpty diff.tool diff.wordRegex difftool. difftool.prompt fetch.unpackLimit format.attach format.cc format.headers format.numbered format.pretty format.signature format.signoff format.subjectprefix format.suffix format.thread gc.aggressiveWindow gc.auto gc.autopacklimit gc.packrefs gc.pruneexpire gc.reflogexpire gc.reflogexpireunreachable gc.rerereresolved gc.rerereunresolved gitcvs.allbinary gitcvs.commitmsgannotation gitcvs.dbTableNamePrefix gitcvs.dbdriver gitcvs.dbname gitcvs.dbpass gitcvs.dbuser gitcvs.enabled gitcvs.logfile gitcvs.usecrlfattr guitool. gui.blamehistoryctx gui.commitmsgwidth gui.copyblamethreshold gui.diffcontext gui.encoding gui.fastcopyblame gui.matchtrackingbranch gui.newbranchtemplate gui.pruneduringfetch gui.spellingdictionary gui.trustmtime help.autocorrect help.browser help.format http.lowSpeedLimit http.lowSpeedTime http.maxRequests http.noEPSV http.proxy http.sslCAInfo http.sslCAPath http.sslCert http.sslKey http.sslVerify i18n.commitEncoding i18n.logOutputEncoding imap.folder imap.host imap.pass imap.port imap.preformattedHTML imap.sslverify imap.tunnel imap.user instaweb.browser instaweb.httpd instaweb.local instaweb.modulepath instaweb.port interactive.singlekey log.date log.showroot mailmap.file man. man.viewer merge.conflictstyle merge.log merge.renameLimit merge.stat merge.tool merge.verbosity mergetool. mergetool.keepBackup mergetool.prompt pack.compression pack.deltaCacheLimit pack.deltaCacheSize pack.depth pack.indexVersion pack.packSizeLimit pack.threads pack.window pack.windowMemory pager. pull.octopus pull.twohead push.default rebase.stat receive.denyCurrentBranch receive.denyDeletes receive.denyNonFastForwards receive.fsckObjects receive.unpackLimit repack.usedeltabaseoffset rerere.autoupdate rerere.enabled sendemail.aliasesfile sendemail.aliasesfiletype sendemail.bcc sendemail.cc sendemail.cccmd sendemail.chainreplyto sendemail.confirm sendemail.envelopesender sendemail.multiedit sendemail.signedoffbycc sendemail.smtpencryption sendemail.smtppass sendemail.smtpserver sendemail.smtpserverport sendemail.smtpuser sendemail.suppresscc sendemail.suppressfrom sendemail.thread sendemail.to sendemail.validate showbranch.default status.relativePaths status.showUntrackedFiles tar.umask transfer.unpackLimit url. user.email user.name user.signingkey web.browser branch. remote. " } _git_remote () { local subcommands="add rename rm show prune update set-head" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" return fi case "$subcommand" in rename|rm|show|prune) __gitcomp "$(__git_remotes)" ;; update) local i c='' IFS=$'\n' for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do i="${i#remotes.}" c="$c ${i/ */}" done __gitcomp "$c" ;; *) COMPREPLY=() ;; esac } _git_replace () { __gitcomp "$(__git_refs)" } _git_reset () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--merge --mixed --hard --soft --patch" return ;; esac __gitcomp "$(__git_refs)" } _git_revert () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--edit --mainline --no-edit --no-commit --signoff" return ;; esac __gitcomp "$(__git_refs)" } _git_rm () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--cached --dry-run --ignore-unmatch --quiet" return ;; esac COMPREPLY=() } _git_shortlog () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " $__git_log_common_options $__git_log_shortlog_options --numbered --summary " return ;; esac __git_complete_revlist } _git_show () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --pretty=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--pretty=}" return ;; --format=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--format=}" return ;; --*) __gitcomp "--pretty= --format= --abbrev-commit --oneline $__git_diff_common_options " return ;; esac __git_complete_file } _git_show_branch () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --all --remotes --topo-order --current --more= --list --independent --merge-base --no-name --color --no-color --sha1-name --sparse --topics --reflog " return ;; esac __git_complete_revlist } _git_stash () { local cur="${COMP_WORDS[COMP_CWORD]}" local save_opts='--keep-index --no-keep-index --quiet --patch' local subcommands='save list show apply clear drop pop create branch' local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then case "$cur" in --*) __gitcomp "$save_opts" ;; *) if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then __gitcomp "$subcommands" else COMPREPLY=() fi ;; esac else case "$subcommand,$cur" in save,--*) __gitcomp "$save_opts" ;; apply,--*|pop,--*) __gitcomp "--index --quiet" ;; show,--*|drop,--*|branch,--*) COMPREPLY=() ;; show,*|apply,*|drop,*|pop,*|branch,*) __gitcomp "$(git --git-dir="$(__gitdir)" stash list \ | sed -n -e 's/:.*//p')" ;; *) COMPREPLY=() ;; esac fi } _git_submodule () { __git_has_doubledash && return local subcommands="add status init update summary foreach sync" if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--quiet --cached" ;; *) __gitcomp "$subcommands" ;; esac return fi } _git_svn () { local subcommands=" init fetch clone rebase dcommit log find-rev set-tree commit-diff info create-ignore propget proplist show-ignore show-externals branch tag blame migrate mkdirs reset gc " local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" else local remote_opts="--username= --config-dir= --no-auth-cache" local fc_opts=" --follow-parent --authors-file= --repack= --no-metadata --use-svm-props --use-svnsync-props --log-window-size= --no-checkout --quiet --repack-flags --use-log-author --localtime --ignore-paths= $remote_opts " local init_opts=" --template= --shared= --trunk= --tags= --branches= --stdlayout --minimize-url --no-metadata --use-svm-props --use-svnsync-props --rewrite-root= --prefix= --use-log-author --add-author-from $remote_opts " local cmt_opts=" --edit --rmdir --find-copies-harder --copy-similarity= " local cur="${COMP_WORDS[COMP_CWORD]}" case "$subcommand,$cur" in fetch,--*) __gitcomp "--revision= --fetch-all $fc_opts" ;; clone,--*) __gitcomp "--revision= $fc_opts $init_opts" ;; init,--*) __gitcomp "$init_opts" ;; dcommit,--*) __gitcomp " --merge --strategy= --verbose --dry-run --fetch-all --no-rebase --commit-url --revision $cmt_opts $fc_opts " ;; set-tree,--*) __gitcomp "--stdin $cmt_opts $fc_opts" ;; create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\ show-externals,--*|mkdirs,--*) __gitcomp "--revision=" ;; log,--*) __gitcomp " --limit= --revision= --verbose --incremental --oneline --show-commit --non-recursive --authors-file= --color " ;; rebase,--*) __gitcomp " --merge --verbose --strategy= --local --fetch-all --dry-run $fc_opts " ;; commit-diff,--*) __gitcomp "--message= --file= --revision= $cmt_opts" ;; info,--*) __gitcomp "--url" ;; branch,--*) __gitcomp "--dry-run --message --tag" ;; tag,--*) __gitcomp "--dry-run --message" ;; blame,--*) __gitcomp "--git-format" ;; migrate,--*) __gitcomp " --config-dir= --ignore-paths= --minimize --no-auth-cache --username= " ;; reset,--*) __gitcomp "--revision= --parent" ;; *) COMPREPLY=() ;; esac fi } _git_tag () { local i c=1 f=0 while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in -d|-v) __gitcomp "$(__git_tags)" return ;; -f) f=1 ;; esac c=$((++c)) done case "${COMP_WORDS[COMP_CWORD-1]}" in -m|-F) COMPREPLY=() ;; -*|tag) if [ $f = 1 ]; then __gitcomp "$(__git_tags)" else COMPREPLY=() fi ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_whatchanged () { _git_log } _git () { local i c=1 command __git_dir while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in --git-dir=*) __git_dir="${i#--git-dir=}" ;; --bare) __git_dir="." ;; --version|-p|--paginate) ;; --help) command="help"; break ;; *) command="$i"; break ;; esac c=$((++c)) done if [ -z "$command" ]; then case "${COMP_WORDS[COMP_CWORD]}" in --*) __gitcomp " --paginate --no-pager --git-dir= --bare --version --exec-path --html-path --work-tree= --help " ;; *) __git_compute_porcelain_commands __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;; esac return fi local completion_func="_git_${command//-/_}" declare -F $completion_func >/dev/null && $completion_func && return local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then completion_func="_git_${expansion//-/_}" declare -F $completion_func >/dev/null && $completion_func fi } _gitk () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" local g="$(__gitdir)" local merge="" if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi case "$cur" in --*) __gitcomp " $__git_log_common_options $__git_log_gitk_options $merge " return ;; esac __git_complete_revlist } complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \ || complete -o default -o nospace -F _git git complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \ || complete -o default -o nospace -F _gitk gitk # The following are necessary only for Cygwin, and only are needed # when the user has tab-completed the executable name and consequently # included the '.exe' suffix. # if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \ || complete -o default -o nospace -F _git git.exe fi